[llvm] r240851 - MIR Serialization: Serialize global address machine operands.

Alex Lorenz arphaman at gmail.com
Fri Jun 26 15:56:49 PDT 2015


Author: arphaman
Date: Fri Jun 26 17:56:48 2015
New Revision: 240851

URL: http://llvm.org/viewvc/llvm-project?rev=240851&view=rev
Log:
MIR Serialization: Serialize global address machine operands.

This commit serializes the global address machine operands.
This commit doesn't serialize the operand's offset and target
flags, it serializes only the global value reference.

Reviewers: Duncan P. N. Exon Smith

Differential Revision: http://reviews.llvm.org/D10671

Added:
    llvm/trunk/test/CodeGen/MIR/X86/global-value-operands.mir
    llvm/trunk/test/CodeGen/MIR/X86/undefined-global-value.mir
    llvm/trunk/test/CodeGen/MIR/X86/undefined-named-global-value.mir
Modified:
    llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp
    llvm/trunk/lib/CodeGen/MIRParser/MILexer.h
    llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
    llvm/trunk/lib/CodeGen/MIRParser/MIParser.h
    llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
    llvm/trunk/lib/CodeGen/MIRPrinter.cpp

Modified: llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp?rev=240851&r1=240850&r2=240851&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp Fri Jun 26 17:56:48 2015
@@ -106,6 +106,25 @@ static Cursor lexPercent(Cursor C, MITok
   return C;
 }
 
+static Cursor lexGlobalValue(Cursor C, MIToken &Token) {
+  auto Range = C;
+  C.advance(); // Skip the '@'
+  // TODO: add support for quoted names.
+  if (!isdigit(C.peek())) {
+    while (isIdentifierChar(C.peek()))
+      C.advance();
+    Token = MIToken(MIToken::NamedGlobalValue, Range.upto(C),
+                    /*StringOffset=*/1); // Drop the '@'
+    return C;
+  }
+  auto NumberRange = C;
+  while (isdigit(C.peek()))
+    C.advance();
+  Token =
+      MIToken(MIToken::GlobalValue, Range.upto(C), APSInt(NumberRange.upto(C)));
+  return C;
+}
+
 static Cursor lexIntegerLiteral(Cursor C, MIToken &Token) {
   auto Range = C;
   C.advance();
@@ -151,6 +170,8 @@ StringRef llvm::lexMIToken(
       return lexMachineBasicBlock(C, Token, ErrorCallback).remaining();
     return lexPercent(C, Token).remaining();
   }
+  if (Char == '@')
+    return lexGlobalValue(C, Token).remaining();
   if (isdigit(Char) || (Char == '-' && isdigit(C.peek(1))))
     return lexIntegerLiteral(C, Token).remaining();
   MIToken::TokenKind Kind = symbolToken(Char);

Modified: llvm/trunk/lib/CodeGen/MIRParser/MILexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MILexer.h?rev=240851&r1=240850&r2=240851&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.h (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.h Fri Jun 26 17:56:48 2015
@@ -40,6 +40,8 @@ struct MIToken {
     Identifier,
     NamedRegister,
     MachineBasicBlock,
+    NamedGlobalValue,
+    GlobalValue,
 
     // Other tokens
     IntegerLiteral
@@ -78,7 +80,8 @@ public:
   const APSInt &integerValue() const { return IntVal; }
 
   bool hasIntegerValue() const {
-    return Kind == IntegerLiteral || Kind == MachineBasicBlock;
+    return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
+           Kind == GlobalValue;
   }
 };
 

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp?rev=240851&r1=240850&r2=240851&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp Fri Jun 26 17:56:48 2015
@@ -14,9 +14,11 @@
 #include "MIParser.h"
 #include "MILexer.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/AsmParser/SlotMapping.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/IR/Module.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Target/TargetSubtargetInfo.h"
@@ -34,6 +36,8 @@ class MIParser {
   MIToken Token;
   /// Maps from basic block numbers to MBBs.
   const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots;
+  /// Maps from indices to unnamed global values and metadata nodes.
+  const SlotMapping &IRSlots;
   /// Maps from instruction names to op codes.
   StringMap<unsigned> Names2InstrOpCodes;
   /// Maps from register names to registers.
@@ -42,7 +46,8 @@ class MIParser {
 public:
   MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error,
            StringRef Source,
-           const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
+           const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots,
+           const SlotMapping &IRSlots);
 
   void lex();
 
@@ -62,6 +67,7 @@ public:
   bool parseRegisterOperand(MachineOperand &Dest, bool IsDef = false);
   bool parseImmediateOperand(MachineOperand &Dest);
   bool parseMBBOperand(MachineOperand &Dest);
+  bool parseGlobalAddressOperand(MachineOperand &Dest);
   bool parseMachineOperand(MachineOperand &Dest);
 
 private:
@@ -89,9 +95,11 @@ private:
 
 MIParser::MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error,
                    StringRef Source,
-                   const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots)
+                   const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots,
+                   const SlotMapping &IRSlots)
     : SM(SM), MF(MF), Error(Error), Source(Source), CurrentSource(Source),
-      Token(MIToken::Error, StringRef()), MBBSlots(MBBSlots) {}
+      Token(MIToken::Error, StringRef()), MBBSlots(MBBSlots), IRSlots(IRSlots) {
+}
 
 void MIParser::lex() {
   CurrentSource = lexMIToken(
@@ -250,6 +258,36 @@ bool MIParser::parseMBBOperand(MachineOp
   return false;
 }
 
+bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) {
+  switch (Token.kind()) {
+  case MIToken::NamedGlobalValue: {
+    auto Name = Token.stringValue();
+    const Module *M = MF.getFunction()->getParent();
+    if (const auto *GV = M->getNamedValue(Name)) {
+      Dest = MachineOperand::CreateGA(GV, /*Offset=*/0);
+      break;
+    }
+    return error(Twine("use of undefined global value '@") + Name + "'");
+  }
+  case MIToken::GlobalValue: {
+    unsigned GVIdx;
+    if (getUnsigned(GVIdx))
+      return true;
+    if (GVIdx >= IRSlots.GlobalValues.size())
+      return error(Twine("use of undefined global value '@") + Twine(GVIdx) +
+                   "'");
+    Dest = MachineOperand::CreateGA(IRSlots.GlobalValues[GVIdx],
+                                    /*Offset=*/0);
+    break;
+  }
+  default:
+    llvm_unreachable("The current token should be a global value");
+  }
+  // TODO: Parse offset and target flags.
+  lex();
+  return false;
+}
+
 bool MIParser::parseMachineOperand(MachineOperand &Dest) {
   switch (Token.kind()) {
   case MIToken::underscore:
@@ -259,6 +297,9 @@ bool MIParser::parseMachineOperand(Machi
     return parseImmediateOperand(Dest);
   case MIToken::MachineBasicBlock:
     return parseMBBOperand(Dest);
+  case MIToken::GlobalValue:
+  case MIToken::NamedGlobalValue:
+    return parseGlobalAddressOperand(Dest);
   case MIToken::Error:
     return true;
   default:
@@ -314,6 +355,6 @@ bool MIParser::getRegisterByName(StringR
 MachineInstr *
 llvm::parseMachineInstr(SourceMgr &SM, MachineFunction &MF, StringRef Src,
                         const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots,
-                        SMDiagnostic &Error) {
-  return MIParser(SM, MF, Error, Src, MBBSlots).parse();
+                        const SlotMapping &IRSlots, SMDiagnostic &Error) {
+  return MIParser(SM, MF, Error, Src, MBBSlots, IRSlots).parse();
 }

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.h?rev=240851&r1=240850&r2=240851&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.h (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.h Fri Jun 26 17:56:48 2015
@@ -22,13 +22,14 @@ namespace llvm {
 class MachineBasicBlock;
 class MachineInstr;
 class MachineFunction;
+struct SlotMapping;
 class SMDiagnostic;
 class SourceMgr;
 
 MachineInstr *
 parseMachineInstr(SourceMgr &SM, MachineFunction &MF, StringRef Src,
                   const DenseMap<unsigned, MachineBasicBlock *> &MBBSlots,
-                  SMDiagnostic &Error);
+                  const SlotMapping &IRSlots, SMDiagnostic &Error);
 
 } // end namespace llvm
 

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp?rev=240851&r1=240850&r2=240851&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp Fri Jun 26 17:56:48 2015
@@ -19,6 +19,7 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/AsmParser/Parser.h"
+#include "llvm/AsmParser/SlotMapping.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MIRYamlMapping.h"
@@ -46,6 +47,7 @@ class MIRParserImpl {
   StringRef Filename;
   LLVMContext &Context;
   StringMap<std::unique_ptr<yaml::MachineFunction>> Functions;
+  SlotMapping IRSlots;
 
 public:
   MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
@@ -157,7 +159,7 @@ std::unique_ptr<Module> MIRParserImpl::p
           dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
     SMDiagnostic Error;
     M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
-                      Context);
+                      Context, &IRSlots);
     if (!M) {
       reportDiagnostic(diagFromLLVMAssemblyDiag(Error, BSN->getSourceRange()));
       return M;
@@ -263,7 +265,8 @@ bool MIRParserImpl::initializeMachineBas
   // Parse the instructions.
   for (const auto &MISource : YamlMBB.Instructions) {
     SMDiagnostic Error;
-    if (auto *MI = parseMachineInstr(SM, MF, MISource.Value, MBBSlots, Error)) {
+    if (auto *MI = parseMachineInstr(SM, MF, MISource.Value, MBBSlots, IRSlots,
+                                     Error)) {
       MBB.insert(MBB.end(), MI);
       continue;
     }

Modified: llvm/trunk/lib/CodeGen/MIRPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRPrinter.cpp?rev=240851&r1=240850&r2=240851&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp Fri Jun 26 17:56:48 2015
@@ -40,16 +40,18 @@ public:
   void print(const MachineFunction &MF);
 
   void convert(yaml::MachineFunction &MF, const MachineRegisterInfo &RegInfo);
-  void convert(yaml::MachineBasicBlock &YamlMBB, const MachineBasicBlock &MBB);
+  void convert(const Module &M, yaml::MachineBasicBlock &YamlMBB,
+               const MachineBasicBlock &MBB);
 };
 
 /// This class prints out the machine instructions using the MIR serialization
 /// format.
 class MIPrinter {
+  const Module &M;
   raw_ostream &OS;
 
 public:
-  MIPrinter(raw_ostream &OS) : OS(OS) {}
+  MIPrinter(const Module &M, raw_ostream &OS) : M(M), OS(OS) {}
 
   void print(const MachineInstr &MI);
   void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
@@ -83,6 +85,7 @@ void MIRPrinter::print(const MachineFunc
   convert(YamlMF, MF.getRegInfo());
 
   int I = 0;
+  const auto &M = *MF.getFunction()->getParent();
   for (const auto &MBB : MF) {
     // TODO: Allow printing of non sequentially numbered MBBs.
     // This is currently needed as the basic block references get their index
@@ -92,7 +95,7 @@ void MIRPrinter::print(const MachineFunc
            "Can't print MBBs that aren't sequentially numbered");
     (void)I;
     yaml::MachineBasicBlock YamlMBB;
-    convert(YamlMBB, MBB);
+    convert(M, YamlMBB, MBB);
     YamlMF.BasicBlocks.push_back(YamlMBB);
   }
   yaml::Output Out(OS);
@@ -106,7 +109,7 @@ void MIRPrinter::convert(yaml::MachineFu
   MF.TracksSubRegLiveness = RegInfo.subRegLivenessEnabled();
 }
 
-void MIRPrinter::convert(yaml::MachineBasicBlock &YamlMBB,
+void MIRPrinter::convert(const Module &M, yaml::MachineBasicBlock &YamlMBB,
                          const MachineBasicBlock &MBB) {
   assert(MBB.getNumber() >= 0 && "Invalid MBB number");
   YamlMBB.ID = (unsigned)MBB.getNumber();
@@ -124,7 +127,7 @@ void MIRPrinter::convert(yaml::MachineBa
   std::string Str;
   for (const auto &MI : MBB) {
     raw_string_ostream StrOS(Str);
-    MIPrinter(StrOS).print(MI);
+    MIPrinter(M, StrOS).print(MI);
     YamlMBB.Instructions.push_back(StrOS.str());
     Str.clear();
   }
@@ -191,6 +194,13 @@ void MIPrinter::print(const MachineOpera
         OS << '.' << BB->getName();
     }
     break;
+  case MachineOperand::MO_GlobalAddress:
+    // FIXME: Make this faster - print as operand will create a slot tracker to
+    // print unnamed values for the whole module every time it's called, which
+    // is inefficient.
+    Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, &M);
+    // TODO: Print offset and target flags.
+    break;
   default:
     // TODO: Print the other machine operands.
     llvm_unreachable("Can't print this machine operand at the moment");

Added: llvm/trunk/test/CodeGen/MIR/X86/global-value-operands.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/global-value-operands.mir?rev=240851&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/global-value-operands.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/global-value-operands.mir Fri Jun 26 17:56:48 2015
@@ -0,0 +1,49 @@
+# RUN: llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s
+# This test ensures that the MIR parser parses global value operands correctly.
+
+--- |
+
+  @G = external global i32
+  @0 = external global i32
+
+  define i32 @inc() {
+  entry:
+    %a = load i32, i32* @G
+    %b = add i32 %a, 1
+    ret i32 %b
+  }
+
+  define i32 @inc2() {
+  entry:
+    %a = load i32, i32* @0
+    %b = add i32 %a, 1
+    ret i32 %b
+  }
+
+...
+---
+# CHECK: name: inc
+name: inc
+body:
+  - id: 0
+    name: entry
+    instructions:
+      # CHECK: - '%rax = MOV64rm %rip, 1, _, @G, _'
+      - '%rax = MOV64rm %rip, 1, _, @G, _'
+      - '%eax = MOV32rm %rax, 1, _, 0, _'
+      - '%eax = INC32r %eax'
+      - 'RETQ %eax'
+...
+---
+# CHECK: name: inc2
+name: inc2
+body:
+  - id: 0
+    name: entry
+    instructions:
+      # CHECK: - '%rax = MOV64rm %rip, 1, _, @0, _'
+      - '%rax = MOV64rm %rip, 1, _, @0, _'
+      - '%eax = MOV32rm %rax, 1, _, 0, _'
+      - '%eax = INC32r %eax'
+      - 'RETQ %eax'
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/undefined-global-value.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/undefined-global-value.mir?rev=240851&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/undefined-global-value.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/undefined-global-value.mir Fri Jun 26 17:56:48 2015
@@ -0,0 +1,28 @@
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+# This test ensures that an error is reported when an invalid global value index
+# is used.
+
+--- |
+
+  @0 = external global i32
+
+  define i32 @inc() {
+  entry:
+    %a = load i32, i32* @0
+    %b = add i32 %a, 1
+    ret i32 %b
+  }
+
+...
+---
+name: inc
+body:
+  - id: 0
+    name: entry
+    instructions:
+      # CHECK: [[@LINE+1]]:37: use of undefined global value '@2'
+      - '%rax = MOV64rm %rip, 1, _, @2, _'
+      - '%eax = MOV32rm %rax, 1, _, 0, _'
+      - '%eax = INC32r %eax'
+      - 'RETQ %eax'
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/undefined-named-global-value.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/undefined-named-global-value.mir?rev=240851&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/undefined-named-global-value.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/undefined-named-global-value.mir Fri Jun 26 17:56:48 2015
@@ -0,0 +1,28 @@
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+# This test ensures that an error is reported when an undefined global value is
+# used.
+
+--- |
+
+  @G = external global i32
+
+  define i32 @inc() {
+  entry:
+    %a = load i32, i32* @G
+    %b = add i32 %a, 1
+    ret i32 %b
+  }
+
+...
+---
+name: inc
+body:
+  - id: 0
+    name: entry
+    instructions:
+      # CHECK: [[@LINE+1]]:37: use of undefined global value '@GG'
+      - '%rax = MOV64rm %rip, 1, _, @GG, _'
+      - '%eax = MOV32rm %rax, 1, _, 0, _'
+      - '%eax = INC32r %eax'
+      - 'RETQ %eax'
+...





More information about the llvm-commits mailing list