[llvm-commits] Fwd: [llvm] r155499 - in /llvm/trunk: include/llvm/Target/Target.td lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp test/MC/ARM/thumb-diagnostics.s utils/TableGen/AsmMatcherEmitter.cpp
David Blaikie
dblaikie at gmail.com
Tue Apr 24 19:05:41 PDT 2012
[oops, sorry Jim - meant to send this to the list to the first time. Resending]
On Tue, Apr 24, 2012 at 3:40 PM, Jim Grosbach <grosbach at apple.com> wrote:
> Author: grosbach
> Date: Tue Apr 24 17:40:08 2012
> New Revision: 155499
>
> URL: http://llvm.org/viewvc/llvm-project?rev=155499&view=rev
> Log:
> ARM: improved assembler diagnostics for missing CPU features.
>
> When an instruction match is found, but the subtarget features it
> requires are not available (missing floating point unit, or thumb vs arm
> mode, for example), issue a diagnostic that identifies what the feature
> mismatch is.
>
> rdar://11257547
>
> Modified:
> llvm/trunk/include/llvm/Target/Target.td
> llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
> llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
> llvm/trunk/test/MC/ARM/thumb-diagnostics.s
> llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
>
> Modified: llvm/trunk/include/llvm/Target/Target.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=155499&r1=155498&r2=155499&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Target/Target.td (original)
> +++ llvm/trunk/include/llvm/Target/Target.td Tue Apr 24 17:40:08 2012
> @@ -438,6 +438,10 @@
> /// e.g. "ModeThumb,FeatureThumb2" is translated to
> /// "(Bits & ModeThumb) != 0 && (Bits & FeatureThumb2) != 0".
> string AssemblerCondString = "";
> +
> + /// PredicateName - User-level name to use for the predicate. Mainly for use
> + /// in diagnostics such as missing feature errors in the asm matcher.
> + string PredicateName = "";
> }
>
> /// NoHonorSignDependentRounding - This predicate is true if support for
> @@ -761,9 +765,10 @@
>
> /// AssemblerPredicate - This is a Predicate that can be used when the assembler
> /// matches instructions and aliases.
> -class AssemblerPredicate<string cond> {
> +class AssemblerPredicate<string cond, string name = ""> {
> bit AssemblerMatcherPredicate = 1;
> string AssemblerCondString = cond;
> + string PredicateName = name;
> }
>
> /// TokenAlias - This class allows targets to define assembler token
>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=155499&r1=155498&r2=155499&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Apr 24 17:40:08 2012
> @@ -161,53 +161,59 @@
> // ARM Instruction Predicate Definitions.
> //
> def HasV4T : Predicate<"Subtarget->hasV4TOps()">,
> - AssemblerPredicate<"HasV4TOps">;
> + AssemblerPredicate<"HasV4TOps", "armv4t">;
> def NoV4T : Predicate<"!Subtarget->hasV4TOps()">;
> def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
> def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">,
> - AssemblerPredicate<"HasV5TEOps">;
> + AssemblerPredicate<"HasV5TEOps", "armv5te">;
> def HasV6 : Predicate<"Subtarget->hasV6Ops()">,
> - AssemblerPredicate<"HasV6Ops">;
> + AssemblerPredicate<"HasV6Ops", "armv6">;
> def NoV6 : Predicate<"!Subtarget->hasV6Ops()">;
> def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">,
> - AssemblerPredicate<"HasV6T2Ops">;
> + AssemblerPredicate<"HasV6T2Ops", "armv6t2">;
> def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">;
> def HasV7 : Predicate<"Subtarget->hasV7Ops()">,
> - AssemblerPredicate<"HasV7Ops">;
> + AssemblerPredicate<"HasV7Ops", "armv7">;
> def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
> def HasVFP2 : Predicate<"Subtarget->hasVFP2()">,
> - AssemblerPredicate<"FeatureVFP2">;
> + AssemblerPredicate<"FeatureVFP2", "VFP2">;
> def HasVFP3 : Predicate<"Subtarget->hasVFP3()">,
> - AssemblerPredicate<"FeatureVFP3">;
> + AssemblerPredicate<"FeatureVFP3", "VFP3">;
> def HasVFP4 : Predicate<"Subtarget->hasVFP4()">,
> - AssemblerPredicate<"FeatureVFP4">;
> + AssemblerPredicate<"FeatureVFP4", "VFP4">;
> def HasNEON : Predicate<"Subtarget->hasNEON()">,
> - AssemblerPredicate<"FeatureNEON">;
> + AssemblerPredicate<"FeatureNEON", "NEON">;
> def HasFP16 : Predicate<"Subtarget->hasFP16()">,
> - AssemblerPredicate<"FeatureFP16">;
> + AssemblerPredicate<"FeatureFP16","half-float">;
> def HasDivide : Predicate<"Subtarget->hasDivide()">,
> - AssemblerPredicate<"FeatureHWDiv">;
> + AssemblerPredicate<"FeatureHWDiv", "divide">;
> def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">,
> - AssemblerPredicate<"FeatureT2XtPk">;
> + AssemblerPredicate<"FeatureT2XtPk",
> + "pack/extract">;
> def HasThumb2DSP : Predicate<"Subtarget->hasThumb2DSP()">,
> - AssemblerPredicate<"FeatureDSPThumb2">;
> + AssemblerPredicate<"FeatureDSPThumb2",
> + "thumb2-dsp">;
> def HasDB : Predicate<"Subtarget->hasDataBarrier()">,
> - AssemblerPredicate<"FeatureDB">;
> + AssemblerPredicate<"FeatureDB",
> + "data-barriers">;
> def HasMP : Predicate<"Subtarget->hasMPExtension()">,
> - AssemblerPredicate<"FeatureMP">;
> + AssemblerPredicate<"FeatureMP",
> + "mp-extensions">;
> def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">;
> def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">;
> def IsThumb : Predicate<"Subtarget->isThumb()">,
> - AssemblerPredicate<"ModeThumb">;
> + AssemblerPredicate<"ModeThumb", "thumb">;
> def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
> def IsThumb2 : Predicate<"Subtarget->isThumb2()">,
> - AssemblerPredicate<"ModeThumb,FeatureThumb2">;
> + AssemblerPredicate<"ModeThumb,FeatureThumb2",
> + "thumb2">;
> def IsMClass : Predicate<"Subtarget->isMClass()">,
> - AssemblerPredicate<"FeatureMClass">;
> + AssemblerPredicate<"FeatureMClass", "armv7m">;
> def IsARClass : Predicate<"!Subtarget->isMClass()">,
> - AssemblerPredicate<"!FeatureMClass">;
> + AssemblerPredicate<"!FeatureMClass",
> + "armv7a/r">;
> def IsARM : Predicate<"!Subtarget->isThumb()">,
> - AssemblerPredicate<"!ModeThumb">;
> + AssemblerPredicate<"!ModeThumb", "arm-mode">;
> def IsIOS : Predicate<"Subtarget->isTargetIOS()">;
> def IsNotIOS : Predicate<"!Subtarget->isTargetIOS()">;
> def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
>
> Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=155499&r1=155498&r2=155499&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Tue Apr 24 17:40:08 2012
> @@ -7277,6 +7277,7 @@
> return Match_Success;
> }
>
> +static const char *getSubtargetFeatureName(unsigned Val);
> bool ARMAsmParser::
> MatchAndEmitInstruction(SMLoc IDLoc,
> SmallVectorImpl<MCParsedAsmOperand*> &Operands,
> @@ -7317,9 +7318,21 @@
> Inst.setLoc(IDLoc);
> Out.EmitInstruction(Inst);
> return false;
> - case Match_MissingFeature:
> - Error(IDLoc, "instruction requires a CPU feature not currently enabled");
> - return true;
> + case Match_MissingFeature: {
> + assert(ErrorInfo && "Unknown missing feature!");
> + // Special case the error message for the very common case where only
> + // a single subtarget feature is missing (Thumb vs. ARM, e.g.).
> + std::string Msg = "instruction requires:";
> + unsigned Mask = 1;
> + for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
> + if (ErrorInfo & Mask) {
> + Msg += " ";
> + Msg += getSubtargetFeatureName(ErrorInfo & Mask);
> + }
> + Mask <<= 1;
> + }
> + return Error(IDLoc, Msg);
> + }
> case Match_InvalidOperand: {
> SMLoc ErrorLoc = IDLoc;
> if (ErrorInfo != ~0U) {
>
> Modified: llvm/trunk/test/MC/ARM/thumb-diagnostics.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb-diagnostics.s?rev=155499&r1=155498&r2=155499&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/ARM/thumb-diagnostics.s (original)
> +++ llvm/trunk/test/MC/ARM/thumb-diagnostics.s Tue Apr 24 17:40:08 2012
> @@ -67,7 +67,7 @@
> @ Invalid writeback and register lists for STM
> stm r1, {r2, r6}
> stm r1!, {r2, r9}
> -@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled
> +@ CHECK-ERRORS: error: instruction requires: thumb2
> @ CHECK-ERRORS: stm r1, {r2, r6}
> @ CHECK-ERRORS: ^
> @ CHECK-ERRORS: error: registers must be in range r0-r7
> @@ -95,13 +95,13 @@
> str r2, [r7, #-1]
> str r5, [r1, #3]
> str r3, [r7, #128]
> -@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled
> +@ CHECK-ERRORS: error: instruction requires: thumb2
> @ CHECK-ERRORS: str r2, [r7, #-1]
> @ CHECK-ERRORS: ^
> -@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled
> +@ CHECK-ERRORS: error: instruction requires: thumb2
> @ CHECK-ERRORS: str r5, [r1, #3]
> @ CHECK-ERRORS: ^
> -@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled
> +@ CHECK-ERRORS: error: instruction requires: thumb2
> @ CHECK-ERRORS: str r3, [r7, #128]
> @ CHECK-ERRORS: ^
>
> @@ -111,7 +111,7 @@
> @ CHECK-ERRORS: error: invalid operand for instruction
> @ CHECK-ERRORS: svc #-1
> @ CHECK-ERRORS: ^
> -@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled
> +@ CHECK-ERRORS: error: instruction requires: arm-mode
> @ CHECK-ERRORS: svc #256
> @ CHECK-ERRORS: ^
>
> @@ -121,15 +121,15 @@
> add sp, #3
> add sp, sp, #512
> add r2, sp, #1024
> -@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled
> +@ CHECK-ERRORS: error: instruction requires: thumb2
> @ CHECK-ERRORS: add sp, #-1
> @ CHECK-ERRORS: ^
> -@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled
> +@ CHECK-ERRORS: error: instruction requires: thumb2
> @ CHECK-ERRORS: add sp, #3
> @ CHECK-ERRORS: ^
> -@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled
> +@ CHECK-ERRORS: error: instruction requires: thumb2
> @ CHECK-ERRORS: add sp, sp, #512
> @ CHECK-ERRORS: ^
> -@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled
> +@ CHECK-ERRORS: error: instruction requires: arm-mode
> @ CHECK-ERRORS: add r2, sp, #1024
> @ CHECK-ERRORS: ^
>
> Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=155499&r1=155498&r2=155499&view=diff
> ==============================================================================
> --- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
> +++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Tue Apr 24 17:40:08 2012
> @@ -1951,6 +1951,25 @@
> OS << "};\n\n";
> }
>
> +/// emitGetSubtargetFeatureName - Emit the helper function to get the
> +/// user-level name for a subtarget feature.
> +static void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) {
> + OS << "// User-level names for subtarget features that participate in\n"
> + << "// instruction matching.\n"
> + << "static const char *getSubtargetFeatureName(unsigned Val) {\n"
For what it's worth, this is producing warnings (errors for those with
-Werror) under clang:
llvm/lib/Target/X86/AsmParser/../X86GenAsmMatcher.inc:639: warning:
‘const char* getSubtargetFeatureName(unsigned int)’ defined but not
used
lib/Target/MBlaze/AsmParser/../MBlazeGenAsmMatcher.inc:267: warning:
‘const char* getSubtargetFeatureName(unsigned int)’ defined but not
used
I'm poking at this to see if I can find the right way to fix this -
but I'm open to suggestions.
> + << " switch(Val) {\n";
> + for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
> + it = Info.SubtargetFeatures.begin(),
> + ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
> + SubtargetFeatureInfo &SFI = *it->second;
> + // FIXME: Totally just a placeholder name to get the algorithm working.
> + OS << " case " << SFI.getEnumName() << ": return \""
> + << SFI.TheDef->getValueAsString("PredicateName") << "\";\n";
> + }
> + OS << " default: return \"(unknown)\";\n";
> + OS << " }\n}\n\n";
> +}
> +
> /// emitComputeAvailableFeatures - Emit the function to compute the list of
> /// available features given a subtarget.
> static void emitComputeAvailableFeatures(AsmMatcherInfo &Info,
> @@ -2380,6 +2399,9 @@
> OS << "\n#ifdef GET_MATCHER_IMPLEMENTATION\n";
> OS << "#undef GET_MATCHER_IMPLEMENTATION\n\n";
>
> + // Generate the helper function to get the names for subtarget features.
> + emitGetSubtargetFeatureName(Info, OS);
> +
> // Generate the function that remaps for mnemonic aliases.
> bool HasMnemonicAliases = emitMnemonicAliases(OS, Info);
>
> @@ -2510,8 +2532,8 @@
> << Target.getName() << ClassName << "::\n"
> << "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
> << " &Operands,\n";
> - OS << " MCInst &Inst, unsigned &ErrorInfo,\n";
> - OS << " unsigned VariantID) {\n";
> + OS << " MCInst &Inst, unsigned &ErrorInfo, ";
> + OS << "unsigned VariantID) {\n";
>
> // Emit code to get the available features.
> OS << " // Get the current feature set.\n";
> @@ -2586,6 +2608,7 @@
> OS << " if ((AvailableFeatures & it->RequiredFeatures) "
> << "!= it->RequiredFeatures) {\n";
> OS << " HadMatchOtherThanFeatures = true;\n";
> + OS << " ErrorInfo = it->RequiredFeatures & ~AvailableFeatures;\n";
> OS << " continue;\n";
> OS << " }\n";
> OS << "\n";
> @@ -2620,6 +2643,7 @@
> OS << " // Okay, we had no match. Try to return a useful error code.\n";
> OS << " if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)";
> OS << " return RetCode;\n";
> + OS << " assert(ErrorInfo && \"missing feature(s) but what?!\");";
> OS << " return Match_MissingFeature;\n";
> OS << "}\n\n";
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list