diff options
author | Evan Cheng <evan.cheng@apple.com> | 2011-07-08 01:53:10 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2011-07-08 01:53:10 +0000 |
commit | ebdeeab812beec0385b445f3d4c41a114e0d972f (patch) | |
tree | 20eaafc6f227ca94201b0b6ac02d94b06b608229 | |
parent | 1fb0955cab05ff71f5bbad523b0374db3b08b201 (diff) |
Eliminate asm parser's dependency on TargetMachine:
- Each target asm parser now creates its own MCSubtatgetInfo (if needed).
- Changed AssemblerPredicate to take subtarget features which tablegen uses
to generate asm matcher subtarget feature queries. e.g.
"ModeThumb,FeatureThumb2" is translated to
"(Bits & ModeThumb) != 0 && (Bits & FeatureThumb2) != 0".
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134678 91177308-0d34-0410-b5e6-96231b3b80d8
49 files changed, 318 insertions, 297 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 7f2cbe2ebc..afc6aa65e5 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -382,6 +382,15 @@ class Predicate<string cond> { /// matcher, this is true. Targets should set this by inheriting their /// feature from the AssemblerPredicate class in addition to Predicate. bit AssemblerMatcherPredicate = 0; + + /// AssemblerCondString - Name of the subtarget feature being tested used + /// as alternative condition string used for assembler matcher. + /// e.g. "ModeThumb" is translated to "(Bits & ModeThumb) != 0". + /// "!ModeThumb" is translated to "(Bits & ModeThumb) == 0". + /// It can also list multiple features separated by ",". + /// e.g. "ModeThumb,FeatureThumb2" is translated to + /// "(Bits & ModeThumb) != 0 && (Bits & FeatureThumb2) != 0". + string AssemblerCondString = ""; } /// NoHonorSignDependentRounding - This predicate is true if support for @@ -689,8 +698,9 @@ def DefaultAsmParser : AsmParser; /// AssemblerPredicate - This is a Predicate that can be used when the assembler /// matches instructions and aliases. -class AssemblerPredicate { +class AssemblerPredicate<string cond> { bit AssemblerMatcherPredicate = 1; + string AssemblerCondString = cond; } diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 01fdb574da..ac41a58ccd 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -14,6 +14,7 @@ #ifndef LLVM_TARGET_TARGETMACHINE_H #define LLVM_TARGET_TARGETMACHINE_H +#include "llvm/ADT/StringRef.h" #include <cassert> #include <string> @@ -91,7 +92,8 @@ class TargetMachine { TargetMachine(const TargetMachine &); // DO NOT IMPLEMENT void operator=(const TargetMachine &); // DO NOT IMPLEMENT protected: // Can only create subclasses. - TargetMachine(const Target &); + TargetMachine(const Target &T, StringRef TargetTriple, + StringRef CPU, StringRef FS); /// getSubtargetImpl - virtual method implemented by subclasses that returns /// a reference to that target's TargetSubtargetInfo-derived member variable. @@ -100,6 +102,12 @@ protected: // Can only create subclasses. /// TheTarget - The Target that this machine was created for. const Target &TheTarget; + /// TargetTriple, TargetCPU, TargetFS - Triple string, CPU name, and target + /// feature strings the TargetMachine instance is created with. + std::string TargetTriple; + std::string TargetCPU; + std::string TargetFS; + /// AsmInfo - Contains target specific asm information. /// const MCAsmInfo *AsmInfo; @@ -115,6 +123,10 @@ public: const Target &getTarget() const { return TheTarget; } + const StringRef getTargetTriple() const { return TargetTriple; } + const StringRef getTargetCPU() const { return TargetCPU; } + const StringRef getTargetFeatureString() const { return TargetFS; } + // Interfaces to the major aspects of target machine information: // -- Instruction opcode and operand information // -- Pipelines and scheduling information @@ -295,10 +307,9 @@ public: /// implemented with the LLVM target-independent code generator. /// class LLVMTargetMachine : public TargetMachine { - std::string TargetTriple; - protected: // Can only create subclasses. - LLVMTargetMachine(const Target &T, const std::string &TargetTriple); + LLVMTargetMachine(const Target &T, StringRef TargetTriple, + StringRef CPU, StringRef FS); private: /// addCommonCodeGenPasses - Add standard LLVM codegen passes used for @@ -311,9 +322,6 @@ private: virtual void setCodeModelForStatic(); public: - - const std::string &getTargetTriple() const { return TargetTriple; } - /// addPassesToEmitFile - Add passes to the specified pass manager to get the /// specified file emitted. Typically this will involve several steps of code /// generation. If OptLevel is None, the code generator should emit code as diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h index efc4438014..00b009a52e 100644 --- a/include/llvm/Target/TargetRegistry.h +++ b/include/llvm/Target/TargetRegistry.h @@ -35,7 +35,6 @@ namespace llvm { class MCInstPrinter; class MCInstrInfo; class MCRegisterInfo; - class MCSubtargetInfo; class MCStreamer; class TargetAsmBackend; class TargetAsmLexer; @@ -70,9 +69,6 @@ namespace llvm { StringRef TT); typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void); typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(void); - typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT, - StringRef CPU, - StringRef Features); typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T, const std::string &TT, const std::string &CPU, @@ -83,8 +79,9 @@ namespace llvm { const std::string &TT); typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T, const MCAsmInfo &MAI); - typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser &P, - TargetMachine &TM); + typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T, StringRef TT, + StringRef CPU, StringRef Features, + MCAsmParser &P); typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T); typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, unsigned SyntaxVariant, @@ -140,10 +137,6 @@ namespace llvm { /// if registered. MCRegInfoCtorFnTy MCRegInfoCtorFn; - /// MCSubtargetInfoCtorFn - Constructor function for this target's - /// MCSubtargetInfo, if registered. - MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn; - /// TargetMachineCtorFn - Construction function for this target's /// TargetMachine, if registered. TargetMachineCtorTy TargetMachineCtorFn; @@ -269,22 +262,6 @@ namespace llvm { return MCRegInfoCtorFn(); } - /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation. - /// - /// \arg Triple - This argument is used to determine the target machine - /// feature set; it should always be provided. Generally this should be - /// either the target triple from the module, or the target triple of the - /// host if that does not exist. - /// \arg CPU - This specifies the name of the target CPU. - /// \arg Features - This specifies the string representation of the - /// additional target features. - MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU, - StringRef Features) const { - if (!MCSubtargetInfoCtorFn) - return 0; - return MCSubtargetInfoCtorFn(Triple, CPU, Features); - } - /// createTargetMachine - Create a target specific machine implementation /// for the specified \arg Triple. /// @@ -322,11 +299,11 @@ namespace llvm { /// /// \arg Parser - The target independent parser implementation to use for /// parsing and lexing. - TargetAsmParser *createAsmParser(MCAsmParser &Parser, - TargetMachine &TM) const { + TargetAsmParser *createAsmParser(StringRef Triple, StringRef CPU, + StringRef Features, MCAsmParser &Parser) const { if (!AsmParserCtorFn) return 0; - return AsmParserCtorFn(*this, Parser, TM); + return AsmParserCtorFn(*this, Triple, CPU, Features, Parser); } /// createAsmPrinter - Create a target specific assembly printer pass. This @@ -528,22 +505,6 @@ namespace llvm { T.MCRegInfoCtorFn = Fn; } - /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for - /// the given target. - /// - /// Clients are responsible for ensuring that registration doesn't occur - /// while another thread is attempting to access the registry. Typically - /// this is done by initializing all targets at program startup. - /// - /// @param T - The target being registered. - /// @param Fn - A function to construct a MCSubtargetInfo for the target. - static void RegisterMCSubtargetInfo(Target &T, - Target::MCSubtargetInfoCtorFnTy Fn) { - // Ignore duplicate registration. - if (!T.MCSubtargetInfoCtorFn) - T.MCSubtargetInfoCtorFn = Fn; - } - /// RegisterTargetMachine - Register a TargetMachine implementation for the /// given target. /// @@ -820,40 +781,6 @@ namespace llvm { } }; - /// RegisterMCSubtargetInfo - Helper template for registering a target - /// subtarget info implementation. This invokes the static "Create" method - /// on the class to actually do the construction. Usage: - /// - /// extern "C" void LLVMInitializeFooTarget() { - /// extern Target TheFooTarget; - /// RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget); - /// } - template<class MCSubtargetInfoImpl> - struct RegisterMCSubtargetInfo { - RegisterMCSubtargetInfo(Target &T) { - TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator); - } - private: - static MCSubtargetInfo *Allocator(StringRef TT, StringRef CPU, - StringRef FS) { - return new MCSubtargetInfoImpl(); - } - }; - - /// RegisterMCSubtargetInfoFn - Helper template for registering a target - /// subtarget info implementation. This invokes the specified function to - /// do the construction. Usage: - /// - /// extern "C" void LLVMInitializeFooTarget() { - /// extern Target TheFooTarget; - /// RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction); - /// } - struct RegisterMCSubtargetInfoFn { - RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) { - TargetRegistry::RegisterMCSubtargetInfo(T, Fn); - } - }; - /// RegisterTargetMachine - Helper template for registering a target machine /// implementation, for use in the target machine initialization /// function. Usage: @@ -931,9 +858,10 @@ namespace llvm { } private: - static TargetAsmParser *Allocator(const Target &T, MCAsmParser &P, - TargetMachine &TM) { - return new AsmParserImpl(T, P, TM); + static TargetAsmParser *Allocator(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, + MCAsmParser &P) { + return new AsmParserImpl(T, TT, CPU, FS, P); } }; diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index c6166e2365..dc843856cd 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -111,7 +111,12 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode) const { OwningPtr<MCAsmParser> Parser(createMCAsmParser(TM.getTarget(), SrcMgr, OutContext, OutStreamer, *MAI)); - OwningPtr<TargetAsmParser> TAP(TM.getTarget().createAsmParser(*Parser, TM)); + + OwningPtr<TargetAsmParser> + TAP(TM.getTarget().createAsmParser(TM.getTargetTriple(), + TM.getTargetCPU(), + TM.getTargetFeatureString(), + *Parser)); if (!TAP) report_fatal_error("Inline asm not supported by this streamer because" " we don't have an asm parser for this target\n"); diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index 318bf976d4..e3337e4c12 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -98,10 +98,10 @@ static cl::opt<cl::boolOrDefault> EnableFastISelOption("fast-isel", cl::Hidden, cl::desc("Enable the \"fast\" instruction selector")); -LLVMTargetMachine::LLVMTargetMachine(const Target &T, - const std::string &Triple) - : TargetMachine(T), TargetTriple(Triple) { - AsmInfo = T.createAsmInfo(TargetTriple); +LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple, + StringRef CPU, StringRef FS) + : TargetMachine(T, Triple, CPU, FS) { + AsmInfo = T.createAsmInfo(Triple); } // Set the default code model for the JIT for a generic target. @@ -143,7 +143,7 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, TargetAsmBackend *TAB = 0; if (ShowMCEncoding) { MCE = getTarget().createCodeEmitter(*this, *Context); - TAB = getTarget().createAsmBackend(TargetTriple); + TAB = getTarget().createAsmBackend(getTargetTriple()); } MCStreamer *S = getTarget().createAsmStreamer(*Context, Out, @@ -160,12 +160,12 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, // Create the code emitter for the target if it exists. If not, .o file // emission fails. MCCodeEmitter *MCE = getTarget().createCodeEmitter(*this, *Context); - TargetAsmBackend *TAB = getTarget().createAsmBackend(TargetTriple); + TargetAsmBackend *TAB = getTarget().createAsmBackend(getTargetTriple()); if (MCE == 0 || TAB == 0) return true; - AsmStreamer.reset(getTarget().createObjectStreamer(TargetTriple, *Context, - *TAB, Out, MCE, + AsmStreamer.reset(getTarget().createObjectStreamer(getTargetTriple(), + *Context, *TAB, Out, MCE, hasMCRelaxAll(), hasMCNoExecStack())); AsmStreamer.get()->InitSections(); @@ -241,12 +241,12 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, // Create the code emitter for the target if it exists. If not, .o file // emission fails. MCCodeEmitter *MCE = getTarget().createCodeEmitter(*this, *Ctx); - TargetAsmBackend *TAB = getTarget().createAsmBackend(TargetTriple); + TargetAsmBackend *TAB = getTarget().createAsmBackend(getTargetTriple()); if (MCE == 0 || TAB == 0) return true; OwningPtr<MCStreamer> AsmStreamer; - AsmStreamer.reset(getTarget().createObjectStreamer(TargetTriple, *Ctx, + AsmStreamer.reset(getTarget().createObjectStreamer(getTargetTriple(), *Ctx, *TAB, Out, MCE, hasMCRelaxAll(), hasMCNoExecStack())); diff --git a/lib/MC/MCDisassembler/EDDisassembler.cpp b/lib/MC/MCDisassembler/EDDisassembler.cpp index 7f9fcc3af5..a39f002a32 100644 --- a/lib/MC/MCDisassembler/EDDisassembler.cpp +++ b/lib/MC/MCDisassembler/EDDisassembler.cpp @@ -171,7 +171,7 @@ EDDisassembler::EDDisassembler(CPUKey &key) : std::string featureString; TargetMachine.reset(Tgt->createTargetMachine(tripleString, CPU, featureString)); - + const TargetRegisterInfo *registerInfo = TargetMachine->getRegisterInfo(); if (!registerInfo) @@ -183,7 +183,7 @@ EDDisassembler::EDDisassembler(CPUKey &key) : if (!AsmInfo) return; - + Disassembler.reset(Tgt->createMCDisassembler()); if (!Disassembler) @@ -371,8 +371,10 @@ int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands, OwningPtr<MCAsmParser> genericParser(createMCAsmParser(*Tgt, sourceMgr, context, *streamer, *AsmInfo)); - OwningPtr<TargetAsmParser> TargetParser(Tgt->createAsmParser(*genericParser, - *TargetMachine)); + + StringRef triple = tripleFromArch(Key.Arch); + OwningPtr<TargetAsmParser> TargetParser(Tgt->createAsmParser(triple, "", "", + *genericParser)); AsmToken OpcodeToken = genericParser->Lex(); AsmToken NextToken = genericParser->Lex(); // consume next token, because specificParser expects us to diff --git a/lib/MC/MCDisassembler/EDDisassembler.h b/lib/MC/MCDisassembler/EDDisassembler.h index 2fcc09d4be..11d69c151c 100644 --- a/lib/MC/MCDisassembler/EDDisassembler.h +++ b/lib/MC/MCDisassembler/EDDisassembler.h @@ -41,6 +41,7 @@ class MCInstPrinter; class MCInst; class MCParsedAsmOperand; class MCStreamer; +class MCSubtargetInfo; template <typename T> class SmallVectorImpl; class SourceMgr; class Target; diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index a5bd79db9f..788b9450b2 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -147,35 +147,48 @@ def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>; //===----------------------------------------------------------------------===// // ARM Instruction Predicate Definitions. // -def HasV4T : Predicate<"Subtarget->hasV4TOps()">, AssemblerPredicate; +def HasV4T : Predicate<"Subtarget->hasV4TOps()">, + AssemblerPredicate<"HasV4TOps">; def NoV4T : Predicate<"!Subtarget->hasV4TOps()">; def HasV5T : Predicate<"Subtarget->hasV5TOps()">; -def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate; -def HasV6 : Predicate<"Subtarget->hasV6Ops()">, AssemblerPredicate; +def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, + AssemblerPredicate<"HasV5TEOps">; +def HasV6 : Predicate<"Subtarget->hasV6Ops()">, + AssemblerPredicate<"HasV6Ops">; def NoV6 : Predicate<"!Subtarget->hasV6Ops()">; -def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate; +def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, + AssemblerPredicate<"HasV6T2Ops">; def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">; -def HasV7 : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate; +def HasV7 : Predicate<"Subtarget->hasV7Ops()">, + AssemblerPredicate<"HasV7Ops">; def NoVFP : Predicate<"!Subtarget->hasVFP2()">; -def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, AssemblerPredicate; -def HasVFP3 : Predicate<"Subtarget->hasVFP3()">, AssemblerPredicate; -def HasNEON : Predicate<"Subtarget->hasNEON()">, AssemblerPredicate; -def HasFP16 : Predicate<"Subtarget->hasFP16()">, AssemblerPredicate; -def HasDivide : Predicate<"Subtarget->hasDivide()">, AssemblerPredicate; +def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, + AssemblerPredicate<"FeatureVFP2">; +def HasVFP3 : Predicate<"Subtarget->hasVFP3()">, + AssemblerPredicate<"FeatureVFP3">; +def HasNEON : Predicate<"Subtarget->hasNEON()">, + AssemblerPredicate<"FeatureNEON">; +def HasFP16 : Predicate<"Subtarget->hasFP16()">, + AssemblerPredicate<"FeatureFP16">; +def HasDivide : Predicate<"Subtarget->hasDivide()">, + AssemblerPredicate<"FeatureHWDiv">; def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">, - AssemblerPredicate; + AssemblerPredicate<"FeatureT2XtPk">; def HasThumb2DSP : Predicate<"Subtarget->hasThumb2DSP()">, - AssemblerPredicate; + AssemblerPredicate<"FeatureDSPThumb2">; def HasDB : Predicate<"Subtarget->hasDataBarrier()">, - AssemblerPredicate; + AssemblerPredicate<"FeatureDB">; def HasMP : Predicate<"Subtarget->hasMPExtension()">, - AssemblerPredicate; + AssemblerPredicate<"FeatureMP">; def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">; def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">; -def IsThumb : Predicate<"Subtarget->isThumb()">, AssemblerPredicate; +def IsThumb : Predicate<"Subtarget->isThumb()">, + AssemblerPredicate<"ModeThumb">; def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">; -def IsThumb2 : Predicate<"Subtarget->isThumb2()">, AssemblerPredicate; -def IsARM : Predicate<"!Subtarget->isThumb()">, AssemblerPredicate; +def IsThumb2 : Predicate<"Subtarget->isThumb2()">, + AssemblerPredicate<"ModeThumb,FeatureThumb2">; +def IsARM : Predicate<"!Subtarget->isThumb()">, + AssemblerPredicate<"!ModeThumb">; def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">; def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">; diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp index 506fe80362..f4fca351d4 100644 --- a/lib/Target/ARM/ARMSubtarget.cpp +++ b/lib/Target/ARM/ARMSubtarget.cpp @@ -18,9 +18,10 @@ #include "llvm/Support/CommandLine.h" #include "llvm/ADT/SmallVector.h" -#define GET_SUBTARGETINFO_CTOR +#define GET_SUBTARGETINFO_ENUM #define GET_SUBTARGETINFO_MC_DESC #define GET_SUBTARGETINFO_TARGET_DESC +#define GET_SUBTARGETINFO_CTOR #include "ARMGenSubtargetInfo.inc" using namespace llvm; diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp index bb3184ee73..fd7b3bf538 100644 --- a/lib/Target/ARM/ARMTargetMachine.cpp +++ b/lib/Target/ARM/ARMTargetMachine.cpp @@ -80,7 +80,7 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const std::string &TT, const std::string &CPU, const std::string &FS) - : LLVMTargetMachine(T, TT), + : LLVMTargetMachine(T, TT, CPU, FS), Subtarget(TT, CPU, FS), JITInfo(), InstrItins(Subtarget.getInstrItineraryData()) { diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 6952c384f4..5cf3633b43 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -20,6 +20,7 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Target/TargetRegistry.h" #include "llvm/Target/TargetAsmParser.h" #include "llvm/Support/SourceMgr.h" @@ -28,6 +29,10 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" + +#define GET_SUBTARGETINFO_ENUM +#include "ARMGenSubtargetInfo.inc" + using namespace llvm; |