[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