[llvm] r245740 - AsmParser: Save and restore the parsing state for types using SlotMapping.

Alex Lorenz via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 21 14:32:40 PDT 2015


Author: arphaman
Date: Fri Aug 21 16:32:39 2015
New Revision: 245740

URL: http://llvm.org/viewvc/llvm-project?rev=245740&view=rev
Log:
AsmParser: Save and restore the parsing state for types using SlotMapping.

This commit extends the 'SlotMapping' structure and includes mappings for named
and numbered types in it. The LLParser is extended accordingly to fill out
those mappings at the end of module parsing.

This information is useful when we want to parse standalone constant values
at a later stage using the 'parseConstantValue' method. The constant values
can be constant expressions, which can contain references to types. In order
to parse such constant values, we have to restore the internal named and
numbered mappings for the types in LLParser, otherwise the parser will report
a parsing error. Therefore, this commit also introduces a new method called
'restoreParsingState' to LLParser, which uses the slot mappings to restore
some of its internal parsing state.

This commit is required to serialize constant value pointers in the machine
memory operands for the MIR format.

Reviewers: Duncan P. N. Exon Smith

Modified:
    llvm/trunk/include/llvm/AsmParser/Parser.h
    llvm/trunk/include/llvm/AsmParser/SlotMapping.h
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/AsmParser/LLParser.h
    llvm/trunk/lib/AsmParser/Parser.cpp
    llvm/trunk/unittests/AsmParser/AsmParserTest.cpp

Modified: llvm/trunk/include/llvm/AsmParser/Parser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/AsmParser/Parser.h?rev=245740&r1=245739&r2=245740&view=diff
==============================================================================
--- llvm/trunk/include/llvm/AsmParser/Parser.h (original)
+++ llvm/trunk/include/llvm/AsmParser/Parser.h Fri Aug 21 16:32:39 2015
@@ -85,8 +85,11 @@ bool parseAssemblyInto(MemoryBufferRef F
 /// The constant value can be any LLVM constant, including a constant
 /// expression.
 ///
+/// \param Slots The optional slot mapping that will restore the parsing state
+/// of the module.
 /// \return null on error.
-Constant *parseConstantValue(StringRef Asm, SMDiagnostic &Err, const Module &M);
+Constant *parseConstantValue(StringRef Asm, SMDiagnostic &Err, const Module &M,
+                             const SlotMapping *Slots = nullptr);
 
 } // End llvm namespace
 

Modified: llvm/trunk/include/llvm/AsmParser/SlotMapping.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/AsmParser/SlotMapping.h?rev=245740&r1=245739&r2=245740&view=diff
==============================================================================
--- llvm/trunk/include/llvm/AsmParser/SlotMapping.h (original)
+++ llvm/trunk/include/llvm/AsmParser/SlotMapping.h Fri Aug 21 16:32:39 2015
@@ -14,6 +14,7 @@
 #ifndef LLVM_ASMPARSER_SLOTMAPPING_H
 #define LLVM_ASMPARSER_SLOTMAPPING_H
 
+#include "llvm/ADT/StringMap.h"
 #include "llvm/IR/TrackingMDRef.h"
 #include <map>
 #include <vector>
@@ -21,12 +22,19 @@
 namespace llvm {
 
 class GlobalValue;
+class Type;
 
-/// This struct contains the mapping from the slot numbers to unnamed metadata
-/// nodes and global values.
+/// This struct contains the mappings from the slot numbers to unnamed metadata
+/// nodes, global values and types. It also contains the mapping for the named
+/// types.
+/// It can be used to save the parsing state of an LLVM IR module so that the
+/// textual references to the values in the module can be parsed outside of the
+/// module's source.
 struct SlotMapping {
   std::vector<GlobalValue *> GlobalValues;
   std::map<unsigned, TrackingMDNodeRef> MetadataNodes;
+  StringMap<Type *> NamedTypes;
+  std::map<unsigned, Type *> Types;
 };
 
 } // end namespace llvm

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=245740&r1=245739&r2=245740&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Fri Aug 21 16:32:39 2015
@@ -49,7 +49,9 @@ bool LLParser::Run() {
          ValidateEndOfModule();
 }
 
-bool LLParser::parseStandaloneConstantValue(Constant *&C) {
+bool LLParser::parseStandaloneConstantValue(Constant *&C,
+                                            const SlotMapping *Slots) {
+  restoreParsingState(Slots);
   Lex.Lex();
 
   Type *Ty = nullptr;
@@ -60,6 +62,19 @@ bool LLParser::parseStandaloneConstantVa
   return false;
 }
 
+void LLParser::restoreParsingState(const SlotMapping *Slots) {
+  if (!Slots)
+    return;
+  NumberedVals = Slots->GlobalValues;
+  NumberedMetadata = Slots->MetadataNodes;
+  for (const auto &I : Slots->NamedTypes)
+    NamedTypes.insert(
+        std::make_pair(I.getKey(), std::make_pair(I.second, LocTy())));
+  for (const auto &I : Slots->Types)
+    NumberedTypes.insert(
+        std::make_pair(I.first, std::make_pair(I.second, LocTy())));
+}
+
 /// ValidateEndOfModule - Do final validity and sanity checks at the end of the
 /// module.
 bool LLParser::ValidateEndOfModule() {
@@ -181,6 +196,10 @@ bool LLParser::ValidateEndOfModule() {
   // the mapping from LLParser as it doesn't need it anymore.
   Slots->GlobalValues = std::move(NumberedVals);
   Slots->MetadataNodes = std::move(NumberedMetadata);
+  for (const auto &I : NamedTypes)
+    Slots->NamedTypes.insert(std::make_pair(I.getKey(), I.second.first));
+  for (const auto &I : NumberedTypes)
+    Slots->Types.insert(std::make_pair(I.first, I.second.first));
 
   return false;
 }

Modified: llvm/trunk/lib/AsmParser/LLParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=245740&r1=245739&r2=245740&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.h (original)
+++ llvm/trunk/lib/AsmParser/LLParser.h Fri Aug 21 16:32:39 2015
@@ -146,7 +146,7 @@ namespace llvm {
           Slots(Slots), BlockAddressPFS(nullptr) {}
     bool Run();
 
-    bool parseStandaloneConstantValue(Constant *&C);
+    bool parseStandaloneConstantValue(Constant *&C, const SlotMapping *Slots);
 
     LLVMContext &getContext() { return Context; }
 
@@ -159,6 +159,10 @@ namespace llvm {
       return Error(Lex.getLoc(), Msg);
     }
 
+    /// Restore the internal name and slot mappings using the mappings that
+    /// were created at an earlier parsing stage.
+    void restoreParsingState(const SlotMapping *Slots);
+
     /// GetGlobalVal - Get a value with the specified name or ID, creating a
     /// forward reference record if needed.  This can return null if the value
     /// exists but does not have the right type.

Modified: llvm/trunk/lib/AsmParser/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/Parser.cpp?rev=245740&r1=245739&r2=245740&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/Parser.cpp (original)
+++ llvm/trunk/lib/AsmParser/Parser.cpp Fri Aug 21 16:32:39 2015
@@ -68,13 +68,13 @@ std::unique_ptr<Module> llvm::parseAssem
 }
 
 Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err,
-                                   const Module &M) {
+                                   const Module &M, const SlotMapping *Slots) {
   SourceMgr SM;
   std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
   SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
   Constant *C;
   if (LLParser(Asm, SM, Err, const_cast<Module *>(&M))
-          .parseStandaloneConstantValue(C))
+          .parseStandaloneConstantValue(C, Slots))
     return nullptr;
   return C;
 }

Modified: llvm/trunk/unittests/AsmParser/AsmParserTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/AsmParser/AsmParserTest.cpp?rev=245740&r1=245739&r2=245740&view=diff
==============================================================================
--- llvm/trunk/unittests/AsmParser/AsmParserTest.cpp (original)
+++ llvm/trunk/unittests/AsmParser/AsmParserTest.cpp Fri Aug 21 16:32:39 2015
@@ -112,4 +112,40 @@ TEST(AsmParserTest, TypeAndConstantValue
   EXPECT_EQ(Error.getMessage(), "expected end of string");
 }
 
+TEST(AsmParserTest, TypeAndConstantValueWithSlotMappingParsing) {
+  LLVMContext &Ctx = getGlobalContext();
+  SMDiagnostic Error;
+  StringRef Source =
+      "%st = type { i32, i32 }\n"
+      "@v = common global [50 x %st] zeroinitializer, align 16\n"
+      "%0 = type { i32, i32, i32, i32 }\n"
+      "@g = common global [50 x %0] zeroinitializer, align 16\n"
+      "define void @marker4(i64 %d) {\n"
+      "entry:\n"
+      "  %conv = trunc i64 %d to i32\n"
+      "  store i32 %conv, i32* getelementptr inbounds "
+      "    ([50 x %st], [50 x %st]* @v, i64 0, i64 0, i32 0), align 16\n"
+      "  store i32 %conv, i32* getelementptr inbounds "
+      "    ([50 x %0], [50 x %0]* @g, i64 0, i64 0, i32 0), align 16\n"
+      "  ret void\n"
+      "}";
+  SlotMapping Mapping;
+  auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping);
+  ASSERT_TRUE(Mod != nullptr);
+  auto &M = *Mod;
+
+  const Value *V;
+  V = parseConstantValue("i32* getelementptr inbounds ([50 x %st], [50 x %st]* "
+                         "@v, i64 0, i64 0, i32 0)",
+                         Error, M, &Mapping);
+  ASSERT_TRUE(V);
+  ASSERT_TRUE(isa<ConstantExpr>(V));
+
+  V = parseConstantValue("i32* getelementptr inbounds ([50 x %0], [50 x %0]* "
+                         "@g, i64 0, i64 0, i32 0)",
+                         Error, M, &Mapping);
+  ASSERT_TRUE(V);
+  ASSERT_TRUE(isa<ConstantExpr>(V));
+}
+
 } // end anonymous namespace




More information about the llvm-commits mailing list