Skip to content

[mlir][Parser][NFC] Make parseFloatFromIntegerLiteral a standalone function #116171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

matthias-springer
Copy link
Member

Make parseFloatFromIntegerLiteral a standalone function, so that it can be reused in a newly added helper function (in a future commit).

Also drop the typeSizeInBits argument. It can be taken from the APFloat semantics.

@llvmbot llvmbot added mlir:core MLIR Core Infrastructure mlir labels Nov 14, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 14, 2024

@llvm/pr-subscribers-mlir

Author: Matthias Springer (matthias-springer)

Changes

Make parseFloatFromIntegerLiteral a standalone function, so that it can be reused in a newly added helper function (in a future commit).

Also drop the typeSizeInBits argument. It can be taken from the APFloat semantics.


Full diff: https://github.com/llvm/llvm-project/pull/116171.diff

4 Files Affected:

  • (modified) mlir/lib/AsmParser/AsmParserImpl.h (+6-7)
  • (modified) mlir/lib/AsmParser/AttributeParser.cpp (+13-11)
  • (modified) mlir/lib/AsmParser/Parser.cpp (+32-31)
  • (modified) mlir/lib/AsmParser/Parser.h (+6-6)
diff --git a/mlir/lib/AsmParser/AsmParserImpl.h b/mlir/lib/AsmParser/AsmParserImpl.h
index 04250f63dcd253..1e6cbc0ec51beb 100644
--- a/mlir/lib/AsmParser/AsmParserImpl.h
+++ b/mlir/lib/AsmParser/AsmParserImpl.h
@@ -287,13 +287,13 @@ class AsmParserImpl : public BaseT {
                          APFloat &result) override {
     bool isNegative = parser.consumeIf(Token::minus);
     Token curTok = parser.getToken();
-    SMLoc loc = curTok.getLoc();
+    auto emitErrorAtTok = [&]() { return emitError(curTok.getLoc(), ""); };
 
     // Check for a floating point value.
     if (curTok.is(Token::floatliteral)) {
       auto val = curTok.getFloatingPointValue();
       if (!val)
-        return emitError(loc, "floating point value too large");
+        return emitErrorAtTok() << "floating point value too large";
       parser.consumeToken(Token::floatliteral);
       result = APFloat(isNegative ? -*val : *val);
       bool losesInfo;
@@ -303,10 +303,9 @@ class AsmParserImpl : public BaseT {
 
     // Check for a hexadecimal float value.
     if (curTok.is(Token::integer)) {
-      std::optional<APFloat> apResult;
-      if (failed(parser.parseFloatFromIntegerLiteral(
-              apResult, curTok, isNegative, semantics,
-              APFloat::semanticsSizeInBits(semantics))))
+      FailureOr<APFloat> apResult = parseFloatFromIntegerLiteral(
+          emitErrorAtTok, curTok, isNegative, semantics);
+      if (failed(apResult))
         return failure();
 
       result = *apResult;
@@ -314,7 +313,7 @@ class AsmParserImpl : public BaseT {
       return success();
     }
 
-    return emitError(loc, "expected floating point literal");
+    return emitErrorAtTok() << "expected floating point literal";
   }
 
   /// Parse a floating point value from the stream.
diff --git a/mlir/lib/AsmParser/AttributeParser.cpp b/mlir/lib/AsmParser/AttributeParser.cpp
index efa65e49abc33b..ba9be3b030453a 100644
--- a/mlir/lib/AsmParser/AttributeParser.cpp
+++ b/mlir/lib/AsmParser/AttributeParser.cpp
@@ -422,10 +422,10 @@ Attribute Parser::parseDecOrHexAttr(Type type, bool isNegative) {
   }
 
   if (auto floatType = dyn_cast<FloatType>(type)) {
-    std::optional<APFloat> result;
-    if (failed(parseFloatFromIntegerLiteral(result, tok, isNegative,
-                                            floatType.getFloatSemantics(),
-                                            floatType.getWidth())))
+    auto emitErrorAtTok = [&]() { return emitError(tok.getLoc()); };
+    FailureOr<APFloat> result = parseFloatFromIntegerLiteral(
+        emitErrorAtTok, tok, isNegative, floatType.getFloatSemantics());
+    if (failed(result))
       return Attribute();
     return FloatAttr::get(floatType, *result);
   }
@@ -661,10 +661,10 @@ TensorLiteralParser::getFloatAttrElements(SMLoc loc, FloatType eltTy,
 
     // Handle hexadecimal float literals.
     if (token.is(Token::integer) && token.getSpelling().starts_with("0x")) {
-      std::optional<APFloat> result;
-      if (failed(p.parseFloatFromIntegerLiteral(result, token, isNegative,
-                                                eltTy.getFloatSemantics(),
-                                                eltTy.getWidth())))
+      auto emitErrorAtTok = [&]() { return p.emitError(token.getLoc()); };
+      FailureOr<APFloat> result = parseFloatFromIntegerLiteral(
+          emitErrorAtTok, token, isNegative, eltTy.getFloatSemantics());
+      if (failed(result))
         return failure();
 
       floatValues.push_back(*result);
@@ -911,10 +911,12 @@ ParseResult DenseArrayElementParser::parseFloatElement(Parser &p) {
   auto floatType = cast<FloatType>(type);
   if (p.consumeIf(Token::integer)) {
     // Parse an integer literal as a float.
-    if (p.parseFloatFromIntegerLiteral(result, token, isNegative,
-                                       floatType.getFloatSemantics(),
-                                       floatType.getWidth()))
+    auto emitErrorAtTok = [&]() { return p.emitError(token.getLoc()); };
+    FailureOr<APFloat> fromIntLit = parseFloatFromIntegerLiteral(
+        emitErrorAtTok, token, isNegative, floatType.getFloatSemantics());
+    if (failed(fromIntLit))
       return failure();
+    result = *fromIntLit;
   } else if (p.consumeIf(Token::floatliteral)) {
     // Parse a floating point literal.
     std::optional<double> val = token.getFloatingPointValue();
diff --git a/mlir/lib/AsmParser/Parser.cpp b/mlir/lib/AsmParser/Parser.cpp
index 8f19487d80fa39..ac7eec931b1250 100644
--- a/mlir/lib/AsmParser/Parser.cpp
+++ b/mlir/lib/AsmParser/Parser.cpp
@@ -67,6 +67,38 @@
 using namespace mlir;
 using namespace mlir::detail;
 
+/// Parse a floating point value from an integer literal token.
+FailureOr<APFloat> detail::parseFloatFromIntegerLiteral(
+    function_ref<InFlightDiagnostic()> emitError, const Token &tok,
+    bool isNegative, const llvm::fltSemantics &semantics) {
+  StringRef spelling = tok.getSpelling();
+  bool isHex = spelling.size() > 1 && spelling[1] == 'x';
+  if (!isHex) {
+    auto error = emitError();
+    error << "unexpected decimal integer literal for a "
+             "floating point value";
+    error.attachNote() << "add a trailing dot to make the literal a float";
+    return failure();
+  }
+  if (isNegative) {
+    emitError() << "hexadecimal float literal should not have a "
+                   "leading minus";
+    return failure();
+  }
+
+  APInt intValue;
+  tok.getSpelling().getAsInteger(isHex ? 0 : 10, intValue);
+  auto typeSizeInBits = APFloat::semanticsSizeInBits(semantics);
+  if (intValue.getActiveBits() > typeSizeInBits) {
+    return emitError() << "hexadecimal float constant out of range for type";
+    return failure();
+  }
+
+  APInt truncatedValue(typeSizeInBits, intValue.getNumWords(),
+                       intValue.getRawData());
+  return APFloat(semantics, truncatedValue);
+}
+
 //===----------------------------------------------------------------------===//
 // CodeComplete
 //===----------------------------------------------------------------------===//
@@ -347,37 +379,6 @@ OptionalParseResult Parser::parseOptionalDecimalInteger(APInt &result) {
   return success();
 }
 
-/// Parse a floating point value from an integer literal token.
-ParseResult Parser::parseFloatFromIntegerLiteral(
-    std::optional<APFloat> &result, const Token &tok, bool isNegative,
-    const llvm::fltSemantics &semantics, size_t typeSizeInBits) {
-  SMLoc loc = tok.getLoc();
-  StringRef spelling = tok.getSpelling();
-  bool isHex = spelling.size() > 1 && spelling[1] == 'x';
-  if (!isHex) {
-    return emitError(loc, "unexpected decimal integer literal for a "
-                          "floating point value")
-               .attachNote()
-           << "add a trailing dot to make the literal a float";
-  }
-  if (isNegative) {
-    return emitError(loc, "hexadecimal float literal should not have a "
-                          "leading minus");
-  }
-
-  APInt intValue;
-  tok.getSpelling().getAsInteger(isHex ? 0 : 10, intValue);
-  if (intValue.getActiveBits() > typeSizeInBits)
-    return emitError(loc, "hexadecimal float constant out of range for type");
-
-  APInt truncatedValue(typeSizeInBits, intValue.getNumWords(),
-                       intValue.getRawData());
-
-  result.emplace(semantics, truncatedValue);
-
-  return success();
-}
-
 ParseResult Parser::parseOptionalKeyword(StringRef *keyword) {
   // Check that the current token is a keyword.
   if (!isCurrentTokenAKeyword())
diff --git a/mlir/lib/AsmParser/Parser.h b/mlir/lib/AsmParser/Parser.h
index bf91831798056b..fa29264ffe506a 100644
--- a/mlir/lib/AsmParser/Parser.h
+++ b/mlir/lib/AsmParser/Parser.h
@@ -16,6 +16,12 @@
 
 namespace mlir {
 namespace detail {
+/// Parse a floating point value from an integer literal token.
+FailureOr<APFloat>
+parseFloatFromIntegerLiteral(function_ref<InFlightDiagnostic()> emitError,
+                             const Token &tok, bool isNegative,
+                             const llvm::fltSemantics &semantics);
+
 //===----------------------------------------------------------------------===//
 // Parser
 //===----------------------------------------------------------------------===//
@@ -151,12 +157,6 @@ class Parser {
   /// Parse an optional integer value only in decimal format from the stream.
   OptionalParseResult parseOptionalDecimalInteger(APInt &result);
 
-  /// Parse a floating point value from an integer literal token.
-  ParseResult parseFloatFromIntegerLiteral(std::optional<APFloat> &result,
-                                           const Token &tok, bool isNegative,
-                                           const llvm::fltSemantics &semantics,
-                                           size_t typeSizeInBits);
-
   /// Returns true if the current token corresponds to a keyword.
   bool isCurrentTokenAKeyword() const {
     return getToken().isAny(Token::bare_identifier, Token::inttype) ||

@llvmbot
Copy link
Member

llvmbot commented Nov 14, 2024

@llvm/pr-subscribers-mlir-core

Author: Matthias Springer (matthias-springer)

Changes

Make parseFloatFromIntegerLiteral a standalone function, so that it can be reused in a newly added helper function (in a future commit).

Also drop the typeSizeInBits argument. It can be taken from the APFloat semantics.


Full diff: https://github.com/llvm/llvm-project/pull/116171.diff

4 Files Affected:

  • (modified) mlir/lib/AsmParser/AsmParserImpl.h (+6-7)
  • (modified) mlir/lib/AsmParser/AttributeParser.cpp (+13-11)
  • (modified) mlir/lib/AsmParser/Parser.cpp (+32-31)
  • (modified) mlir/lib/AsmParser/Parser.h (+6-6)
diff --git a/mlir/lib/AsmParser/AsmParserImpl.h b/mlir/lib/AsmParser/AsmParserImpl.h
index 04250f63dcd253..1e6cbc0ec51beb 100644
--- a/mlir/lib/AsmParser/AsmParserImpl.h
+++ b/mlir/lib/AsmParser/AsmParserImpl.h
@@ -287,13 +287,13 @@ class AsmParserImpl : public BaseT {
                          APFloat &result) override {
     bool isNegative = parser.consumeIf(Token::minus);
     Token curTok = parser.getToken();
-    SMLoc loc = curTok.getLoc();
+    auto emitErrorAtTok = [&]() { return emitError(curTok.getLoc(), ""); };
 
     // Check for a floating point value.
     if (curTok.is(Token::floatliteral)) {
       auto val = curTok.getFloatingPointValue();
       if (!val)
-        return emitError(loc, "floating point value too large");
+        return emitErrorAtTok() << "floating point value too large";
       parser.consumeToken(Token::floatliteral);
       result = APFloat(isNegative ? -*val : *val);
       bool losesInfo;
@@ -303,10 +303,9 @@ class AsmParserImpl : public BaseT {
 
     // Check for a hexadecimal float value.
     if (curTok.is(Token::integer)) {
-      std::optional<APFloat> apResult;
-      if (failed(parser.parseFloatFromIntegerLiteral(
-              apResult, curTok, isNegative, semantics,
-              APFloat::semanticsSizeInBits(semantics))))
+      FailureOr<APFloat> apResult = parseFloatFromIntegerLiteral(
+          emitErrorAtTok, curTok, isNegative, semantics);
+      if (failed(apResult))
         return failure();
 
       result = *apResult;
@@ -314,7 +313,7 @@ class AsmParserImpl : public BaseT {
       return success();
     }
 
-    return emitError(loc, "expected floating point literal");
+    return emitErrorAtTok() << "expected floating point literal";
   }
 
   /// Parse a floating point value from the stream.
diff --git a/mlir/lib/AsmParser/AttributeParser.cpp b/mlir/lib/AsmParser/AttributeParser.cpp
index efa65e49abc33b..ba9be3b030453a 100644
--- a/mlir/lib/AsmParser/AttributeParser.cpp
+++ b/mlir/lib/AsmParser/AttributeParser.cpp
@@ -422,10 +422,10 @@ Attribute Parser::parseDecOrHexAttr(Type type, bool isNegative) {
   }
 
   if (auto floatType = dyn_cast<FloatType>(type)) {
-    std::optional<APFloat> result;
-    if (failed(parseFloatFromIntegerLiteral(result, tok, isNegative,
-                                            floatType.getFloatSemantics(),
-                                            floatType.getWidth())))
+    auto emitErrorAtTok = [&]() { return emitError(tok.getLoc()); };
+    FailureOr<APFloat> result = parseFloatFromIntegerLiteral(
+        emitErrorAtTok, tok, isNegative, floatType.getFloatSemantics());
+    if (failed(result))
       return Attribute();
     return FloatAttr::get(floatType, *result);
   }
@@ -661,10 +661,10 @@ TensorLiteralParser::getFloatAttrElements(SMLoc loc, FloatType eltTy,
 
     // Handle hexadecimal float literals.
     if (token.is(Token::integer) && token.getSpelling().starts_with("0x")) {
-      std::optional<APFloat> result;
-      if (failed(p.parseFloatFromIntegerLiteral(result, token, isNegative,
-                                                eltTy.getFloatSemantics(),
-                                                eltTy.getWidth())))
+      auto emitErrorAtTok = [&]() { return p.emitError(token.getLoc()); };
+      FailureOr<APFloat> result = parseFloatFromIntegerLiteral(
+          emitErrorAtTok, token, isNegative, eltTy.getFloatSemantics());
+      if (failed(result))
         return failure();
 
       floatValues.push_back(*result);
@@ -911,10 +911,12 @@ ParseResult DenseArrayElementParser::parseFloatElement(Parser &p) {
   auto floatType = cast<FloatType>(type);
   if (p.consumeIf(Token::integer)) {
     // Parse an integer literal as a float.
-    if (p.parseFloatFromIntegerLiteral(result, token, isNegative,
-                                       floatType.getFloatSemantics(),
-                                       floatType.getWidth()))
+    auto emitErrorAtTok = [&]() { return p.emitError(token.getLoc()); };
+    FailureOr<APFloat> fromIntLit = parseFloatFromIntegerLiteral(
+        emitErrorAtTok, token, isNegative, floatType.getFloatSemantics());
+    if (failed(fromIntLit))
       return failure();
+    result = *fromIntLit;
   } else if (p.consumeIf(Token::floatliteral)) {
     // Parse a floating point literal.
     std::optional<double> val = token.getFloatingPointValue();
diff --git a/mlir/lib/AsmParser/Parser.cpp b/mlir/lib/AsmParser/Parser.cpp
index 8f19487d80fa39..ac7eec931b1250 100644
--- a/mlir/lib/AsmParser/Parser.cpp
+++ b/mlir/lib/AsmParser/Parser.cpp
@@ -67,6 +67,38 @@
 using namespace mlir;
 using namespace mlir::detail;
 
+/// Parse a floating point value from an integer literal token.
+FailureOr<APFloat> detail::parseFloatFromIntegerLiteral(
+    function_ref<InFlightDiagnostic()> emitError, const Token &tok,
+    bool isNegative, const llvm::fltSemantics &semantics) {
+  StringRef spelling = tok.getSpelling();
+  bool isHex = spelling.size() > 1 && spelling[1] == 'x';
+  if (!isHex) {
+    auto error = emitError();
+    error << "unexpected decimal integer literal for a "
+             "floating point value";
+    error.attachNote() << "add a trailing dot to make the literal a float";
+    return failure();
+  }
+  if (isNegative) {
+    emitError() << "hexadecimal float literal should not have a "
+                   "leading minus";
+    return failure();
+  }
+
+  APInt intValue;
+  tok.getSpelling().getAsInteger(isHex ? 0 : 10, intValue);
+  auto typeSizeInBits = APFloat::semanticsSizeInBits(semantics);
+  if (intValue.getActiveBits() > typeSizeInBits) {
+    return emitError() << "hexadecimal float constant out of range for type";
+    return failure();
+  }
+
+  APInt truncatedValue(typeSizeInBits, intValue.getNumWords(),
+                       intValue.getRawData());
+  return APFloat(semantics, truncatedValue);
+}
+
 //===----------------------------------------------------------------------===//
 // CodeComplete
 //===----------------------------------------------------------------------===//
@@ -347,37 +379,6 @@ OptionalParseResult Parser::parseOptionalDecimalInteger(APInt &result) {
   return success();
 }
 
-/// Parse a floating point value from an integer literal token.
-ParseResult Parser::parseFloatFromIntegerLiteral(
-    std::optional<APFloat> &result, const Token &tok, bool isNegative,
-    const llvm::fltSemantics &semantics, size_t typeSizeInBits) {
-  SMLoc loc = tok.getLoc();
-  StringRef spelling = tok.getSpelling();
-  bool isHex = spelling.size() > 1 && spelling[1] == 'x';
-  if (!isHex) {
-    return emitError(loc, "unexpected decimal integer literal for a "
-                          "floating point value")
-               .attachNote()
-           << "add a trailing dot to make the literal a float";
-  }
-  if (isNegative) {
-    return emitError(loc, "hexadecimal float literal should not have a "
-                          "leading minus");
-  }
-
-  APInt intValue;
-  tok.getSpelling().getAsInteger(isHex ? 0 : 10, intValue);
-  if (intValue.getActiveBits() > typeSizeInBits)
-    return emitError(loc, "hexadecimal float constant out of range for type");
-
-  APInt truncatedValue(typeSizeInBits, intValue.getNumWords(),
-                       intValue.getRawData());
-
-  result.emplace(semantics, truncatedValue);
-
-  return success();
-}
-
 ParseResult Parser::parseOptionalKeyword(StringRef *keyword) {
   // Check that the current token is a keyword.
   if (!isCurrentTokenAKeyword())
diff --git a/mlir/lib/AsmParser/Parser.h b/mlir/lib/AsmParser/Parser.h
index bf91831798056b..fa29264ffe506a 100644
--- a/mlir/lib/AsmParser/Parser.h
+++ b/mlir/lib/AsmParser/Parser.h
@@ -16,6 +16,12 @@
 
 namespace mlir {
 namespace detail {
+/// Parse a floating point value from an integer literal token.
+FailureOr<APFloat>
+parseFloatFromIntegerLiteral(function_ref<InFlightDiagnostic()> emitError,
+                             const Token &tok, bool isNegative,
+                             const llvm::fltSemantics &semantics);
+
 //===----------------------------------------------------------------------===//
 // Parser
 //===----------------------------------------------------------------------===//
@@ -151,12 +157,6 @@ class Parser {
   /// Parse an optional integer value only in decimal format from the stream.
   OptionalParseResult parseOptionalDecimalInteger(APInt &result);
 
-  /// Parse a floating point value from an integer literal token.
-  ParseResult parseFloatFromIntegerLiteral(std::optional<APFloat> &result,
-                                           const Token &tok, bool isNegative,
-                                           const llvm::fltSemantics &semantics,
-                                           size_t typeSizeInBits);
-
   /// Returns true if the current token corresponds to a keyword.
   bool isCurrentTokenAKeyword() const {
     return getToken().isAny(Token::bare_identifier, Token::inttype) ||

@River707
Copy link
Contributor

Which PR is using the new function? Would be good to see the usage

@matthias-springer
Copy link
Member Author

Which PR is using the new function? Would be good to see the usage

This is in preparation of #116172 and #116176.

@River707
Copy link
Contributor

From reading #116172 I couldn't see the need for making this a standalone function, can you elaborate?

@matthias-springer
Copy link
Member Author

Obsolete due to changes to #116172.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mlir:core MLIR Core Infrastructure mlir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants