[llvm] r243453 - MIR Serialization: Serialize the block address machine operands.

Alex Lorenz arphaman at gmail.com
Tue Jul 28 10:28:04 PDT 2015


Author: arphaman
Date: Tue Jul 28 12:28:03 2015
New Revision: 243453

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

Added:
    llvm/trunk/test/CodeGen/MIR/X86/block-address-operands.mir
    llvm/trunk/test/CodeGen/MIR/X86/expected-block-reference-in-blockaddress.mir
    llvm/trunk/test/CodeGen/MIR/X86/expected-function-reference-after-blockaddress.mir
    llvm/trunk/test/CodeGen/MIR/X86/expected-global-value-after-blockaddress.mir
    llvm/trunk/test/CodeGen/MIR/X86/undefined-ir-block-in-blockaddress.mir
    llvm/trunk/test/CodeGen/MIR/X86/undefined-ir-block-slot-in-blockaddress.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/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=243453&r1=243452&r2=243453&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.cpp Tue Jul 28 12:28:03 2015
@@ -147,6 +147,7 @@ static MIToken::TokenKind getIdentifierK
       .Case(".cfi_offset", MIToken::kw_cfi_offset)
       .Case(".cfi_def_cfa_register", MIToken::kw_cfi_def_cfa_register)
       .Case(".cfi_def_cfa_offset", MIToken::kw_cfi_def_cfa_offset)
+      .Case("blockaddress", MIToken::kw_blockaddress)
       .Default(MIToken::Identifier);
 }
 
@@ -239,8 +240,16 @@ static Cursor maybeLexConstantPoolItem(C
   return maybeLexIndex(C, Token, "%const.", MIToken::ConstantPoolItem);
 }
 
-static Cursor maybeLexIRBlock(Cursor C, MIToken &Token) {
-  return maybeLexIndex(C, Token, "%ir-block.", MIToken::IRBlock);
+static Cursor maybeLexIRBlock(
+    Cursor C, MIToken &Token,
+    function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
+  const StringRef Rule = "%ir-block.";
+  if (!C.remaining().startswith(Rule))
+    return None;
+  if (isdigit(C.peek(Rule.size())))
+    return maybeLexIndex(C, Token, Rule, MIToken::IRBlock);
+  return lexName(C, Token, MIToken::NamedIRBlock, MIToken::QuotedNamedIRBlock,
+                 Rule.size(), ErrorCallback);
 }
 
 static Cursor lexVirtualRegister(Cursor C, MIToken &Token) {
@@ -319,6 +328,10 @@ static MIToken::TokenKind symbolToken(ch
     return MIToken::colon;
   case '!':
     return MIToken::exclaim;
+  case '(':
+    return MIToken::lparen;
+  case ')':
+    return MIToken::rparen;
   default:
     return MIToken::Error;
   }
@@ -355,7 +368,7 @@ StringRef llvm::lexMIToken(
     return R.remaining();
   if (Cursor R = maybeLexConstantPoolItem(C, Token))
     return R.remaining();
-  if (Cursor R = maybeLexIRBlock(C, Token))
+  if (Cursor R = maybeLexIRBlock(C, Token, ErrorCallback))
     return R.remaining();
   if (Cursor R = maybeLexRegister(C, Token))
     return R.remaining();

Modified: llvm/trunk/lib/CodeGen/MIRParser/MILexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MILexer.h?rev=243453&r1=243452&r2=243453&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MILexer.h (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MILexer.h Tue Jul 28 12:28:03 2015
@@ -37,6 +37,8 @@ struct MIToken {
     underscore,
     colon,
     exclaim,
+    lparen,
+    rparen,
 
     // Keywords
     kw_implicit,
@@ -49,6 +51,7 @@ struct MIToken {
     kw_cfi_offset,
     kw_cfi_def_cfa_register,
     kw_cfi_def_cfa_offset,
+    kw_blockaddress,
 
     // Identifier tokens
     Identifier,
@@ -67,6 +70,8 @@ struct MIToken {
     VirtualRegister,
     ConstantPoolItem,
     JumpTableIndex,
+    NamedIRBlock,
+    QuotedNamedIRBlock,
     IRBlock,
   };
 
@@ -105,7 +110,8 @@ public:
   StringRef::iterator location() const { return Range.begin(); }
 
   bool isStringValueQuoted() const {
-    return Kind == QuotedNamedGlobalValue || Kind == QuotedExternalSymbol;
+    return Kind == QuotedNamedGlobalValue || Kind == QuotedExternalSymbol ||
+           Kind == QuotedNamedIRBlock;
   }
 
   /// Return the token's raw string value.

Modified: llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp?rev=243453&r1=243452&r2=243453&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIParser.cpp Tue Jul 28 12:28:03 2015
@@ -22,8 +22,10 @@
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/IR/Instructions.h"
+#include "llvm/IR/Constants.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/ModuleSlotTracker.h"
+#include "llvm/IR/ValueSymbolTable.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Target/TargetSubtargetInfo.h"
@@ -123,6 +125,8 @@ public:
   bool parseCFIOffset(int &Offset);
   bool parseCFIRegister(unsigned &Reg);
   bool parseCFIOperand(MachineOperand &Dest);
+  bool parseIRBlock(BasicBlock *&BB, const Function &F);
+  bool parseBlockAddressOperand(MachineOperand &Dest);
   bool parseMachineOperand(MachineOperand &Dest);
 
 private:
@@ -200,6 +204,10 @@ static const char *toString(MIToken::Tok
   switch (TokenKind) {
   case MIToken::comma:
     return "','";
+  case MIToken::lparen:
+    return "'('";
+  case MIToken::rparen:
+    return "')'";
   default:
     return "<unknown token>";
   }
@@ -741,6 +749,65 @@ bool MIParser::parseCFIOperand(MachineOp
   return false;
 }
 
+bool MIParser::parseIRBlock(BasicBlock *&BB, const Function &F) {
+  switch (Token.kind()) {
+  case MIToken::NamedIRBlock:
+  case MIToken::QuotedNamedIRBlock: {
+    StringValueUtility Name(Token);
+    BB = dyn_cast_or_null<BasicBlock>(F.getValueSymbolTable().lookup(Name));
+    if (!BB)
+      return error(Twine("use of undefined IR block '%ir-block.") +
+                   Token.rawStringValue() + "'");
+    break;
+  }
+  case MIToken::IRBlock: {
+    unsigned SlotNumber = 0;
+    if (getUnsigned(SlotNumber))
+      return true;
+    BB = const_cast<BasicBlock *>(getIRBlock(SlotNumber));
+    if (!BB)
+      return error(Twine("use of undefined IR block '%ir-block.") +
+                   Twine(SlotNumber) + "'");
+    break;
+  }
+  default:
+    llvm_unreachable("The current token should be an IR block reference");
+  }
+  return false;
+}
+
+bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) {
+  assert(Token.is(MIToken::kw_blockaddress));
+  lex();
+  if (expectAndConsume(MIToken::lparen))
+    return true;
+  if (Token.isNot(MIToken::GlobalValue) &&
+      Token.isNot(MIToken::NamedGlobalValue) &&
+      Token.isNot(MIToken::QuotedNamedGlobalValue))
+    return error("expected a global value");
+  GlobalValue *GV = nullptr;
+  if (parseGlobalValue(GV))
+    return true;
+  auto *F = dyn_cast<Function>(GV);
+  if (!F)
+    return error("expected an IR function reference");
+  lex();
+  if (expectAndConsume(MIToken::comma))
+    return true;
+  BasicBlock *BB = nullptr;
+  if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock) &&
+      Token.isNot(MIToken::QuotedNamedIRBlock))
+    return error("expected an IR block reference");
+  if (parseIRBlock(BB, *F))
+    return true;
+  lex();
+  if (expectAndConsume(MIToken::rparen))
+    return true;
+  // TODO: parse offset and target flags.
+  Dest = MachineOperand::CreateBA(BlockAddress::get(F, BB), /*Offset=*/0);
+  return false;
+}
+
 bool MIParser::parseMachineOperand(MachineOperand &Dest) {
   switch (Token.kind()) {
   case MIToken::kw_implicit:
@@ -777,6 +844,8 @@ bool MIParser::parseMachineOperand(Machi
   case MIToken::kw_cfi_def_cfa_register:
   case MIToken::kw_cfi_def_cfa_offset:
     return parseCFIOperand(Dest);
+  case MIToken::kw_blockaddress:
+    return parseBlockAddressOperand(Dest);
   case MIToken::Error:
     return true;
   case MIToken::Identifier:

Modified: llvm/trunk/lib/CodeGen/MIRPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRPrinter.cpp?rev=243453&r1=243452&r2=243453&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp Tue Jul 28 12:28:03 2015
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MIRYamlMapping.h"
 #include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/Module.h"
@@ -103,6 +104,7 @@ public:
 
   void print(const MachineInstr &MI);
   void printMBBReference(const MachineBasicBlock &MBB);
+  void printIRBlockReference(const BasicBlock &BB);
   void printStackObjectReference(int FrameIndex);
   void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
 
@@ -428,6 +430,19 @@ void MIPrinter::printMBBReference(const
   }
 }
 
+void MIPrinter::printIRBlockReference(const BasicBlock &BB) {
+  OS << "%ir-block.";
+  if (BB.hasName()) {
+    printLLVMNameWithoutPrefix(OS, BB.getName());
+    return;
+  }
+  int Slot = MST.getLocalSlot(&BB);
+  if (Slot == -1)
+    OS << "<badref>";
+  else
+    OS << Slot;
+}
+
 void MIPrinter::printStackObjectReference(int FrameIndex) {
   auto ObjectInfo = StackObjectOperandMapping.find(FrameIndex);
   assert(ObjectInfo != StackObjectOperandMapping.end() &&
@@ -485,6 +500,15 @@ void MIPrinter::print(const MachineOpera
     Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
     // TODO: Print offset and target flags.
     break;
+  case MachineOperand::MO_BlockAddress:
+    OS << "blockaddress(";
+    Op.getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false,
+                                                        MST);
+    OS << ", ";
+    printIRBlockReference(*Op.getBlockAddress()->getBasicBlock());
+    OS << ')';
+    // TODO: Print offset and target flags.
+    break;
   case MachineOperand::MO_RegisterMask: {
     auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
     if (RegMaskInfo != RegisterMaskIds.end())

Added: llvm/trunk/test/CodeGen/MIR/X86/block-address-operands.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/block-address-operands.mir?rev=243453&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/block-address-operands.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/block-address-operands.mir Tue Jul 28 12:28:03 2015
@@ -0,0 +1,89 @@
+# 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 the block address operands
+# correctly.
+
+--- |
+
+  @addr = global i8* null
+
+  define void @test() {
+  entry:
+    store volatile i8* blockaddress(@test, %block), i8** @addr
+    %val = load volatile i8*, i8** @addr
+    indirectbr i8* %val, [label %block]
+
+  block:
+    ret void
+  }
+
+  define void @test2() {
+  entry:
+    store volatile i8* blockaddress(@test2, %"quoted block"), i8** @addr
+    %val = load volatile i8*, i8** @addr
+    indirectbr i8* %val, [label %"quoted block"]
+
+  "quoted block":
+    ret void
+  }
+
+  define void @test3() {
+  entry:
+    store volatile i8* blockaddress(@test3, %0), i8** @addr
+    %val = load volatile i8*, i8** @addr
+    indirectbr i8* %val, [label %0]
+
+    ret void
+  }
+
+...
+---
+name:            test
+body:
+  - id:              0
+    name:            entry
+    successors:      [ '%bb.1.block' ]
+    instructions:
+    # CHECK: %rax = LEA64r %rip, 1, _, blockaddress(@test, %ir-block.block), _
+      - '%rax = LEA64r %rip, 1, _, blockaddress(@test, %ir-block.block), _'
+      - 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
+      - 'JMP64m %rip, 1, _, @addr, _'
+  - id:              1
+    name:            block
+    addressTaken:    true
+    instructions:
+      - RETQ
+...
+---
+name:            test2
+tracksRegLiveness: true
+body:
+  - id:              0
+    name:            entry
+    successors:      [ '%bb.1' ]
+    instructions:
+    # CHECK: %rax = LEA64r %rip, 1, _, blockaddress(@test2, %ir-block."quoted block"), _
+      - '%rax = LEA64r %rip, 1, _, blockaddress(@test2, %ir-block."quoted block"), _'
+      - 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
+      - 'JMP64m %rip, 1, _, @addr, _'
+  - id:              1
+    addressTaken:    true
+    instructions:
+      - RETQ
+...
+---
+name:            test3
+tracksRegLiveness: true
+body:
+  - id:              0
+    name:            entry
+    successors:      [ '%bb.1' ]
+    instructions:
+    # CHECK: %rax = LEA64r %rip, 1, _, blockaddress(@test3, %ir-block.0), _
+      - '%rax = LEA64r %rip, 1, _, blockaddress(@test3, %ir-block.0), _'
+      - 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
+      - 'JMP64m %rip, 1, _, @addr, _'
+  - id:              1
+    addressTaken:    true
+    instructions:
+      - RETQ
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/expected-block-reference-in-blockaddress.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/expected-block-reference-in-blockaddress.mir?rev=243453&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/expected-block-reference-in-blockaddress.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/expected-block-reference-in-blockaddress.mir Tue Jul 28 12:28:03 2015
@@ -0,0 +1,34 @@
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+
+--- |
+
+  @addr = global i8* null
+
+  define void @test() {
+  entry:
+    store volatile i8* blockaddress(@test, %block), i8** @addr
+    %val = load volatile i8*, i8** @addr
+    indirectbr i8* %val, [label %block]
+
+  block:
+    ret void
+  }
+
+...
+---
+name:            test
+body:
+  - id:              0
+    name:            entry
+    successors:      [ '%bb.1.block' ]
+    instructions:
+      # CHECK: [[@LINE+1]]:56: expected an IR block reference
+      - '%rax = LEA64r %rip, 1, _, blockaddress(@test, _), _'
+      - 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
+      - 'JMP64m %rip, 1, _, @addr, _'
+  - id:              1
+    name:            block
+    addressTaken:    true
+    instructions:
+      - RETQ
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/expected-function-reference-after-blockaddress.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/expected-function-reference-after-blockaddress.mir?rev=243453&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/expected-function-reference-after-blockaddress.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/expected-function-reference-after-blockaddress.mir Tue Jul 28 12:28:03 2015
@@ -0,0 +1,34 @@
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+
+--- |
+
+  @addr = global i8* null
+
+  define void @test() {
+  entry:
+    store volatile i8* blockaddress(@test, %block), i8** @addr
+    %val = load volatile i8*, i8** @addr
+    indirectbr i8* %val, [label %block]
+
+  block:
+    ret void
+  }
+
+...
+---
+name:            test
+body:
+  - id:              0
+    name:            entry
+    successors:      [ '%bb.1.block' ]
+    instructions:
+      # CHECK: [[@LINE+1]]:49: expected an IR function reference
+      - '%rax = LEA64r %rip, 1, _, blockaddress(@addr, %ir-block.block), _'
+      - 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
+      - 'JMP64m %rip, 1, _, @addr, _'
+  - id:              1
+    name:            block
+    addressTaken:    true
+    instructions:
+      - RETQ
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/expected-global-value-after-blockaddress.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/expected-global-value-after-blockaddress.mir?rev=243453&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/expected-global-value-after-blockaddress.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/expected-global-value-after-blockaddress.mir Tue Jul 28 12:28:03 2015
@@ -0,0 +1,34 @@
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+
+--- |
+
+  @addr = global i8* null
+
+  define void @test() {
+  entry:
+    store volatile i8* blockaddress(@test, %block), i8** @addr
+    %val = load volatile i8*, i8** @addr
+    indirectbr i8* %val, [label %block]
+
+  block:
+    ret void
+  }
+
+...
+---
+name:            test
+body:
+  - id:              0
+    name:            entry
+    successors:      [ '%bb.1.block' ]
+    instructions:
+      # CHECK: [[@LINE+1]]:49: expected a global value
+      - '%rax = LEA64r %rip, 1, _, blockaddress(0, %ir-block.block), _'
+      - 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
+      - 'JMP64m %rip, 1, _, @addr, _'
+  - id:              1
+    name:            block
+    addressTaken:    true
+    instructions:
+      - RETQ
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/undefined-ir-block-in-blockaddress.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/undefined-ir-block-in-blockaddress.mir?rev=243453&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/undefined-ir-block-in-blockaddress.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/undefined-ir-block-in-blockaddress.mir Tue Jul 28 12:28:03 2015
@@ -0,0 +1,34 @@
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+
+--- |
+
+  @addr = global i8* null
+
+  define void @test() {
+  entry:
+    store volatile i8* blockaddress(@test, %block), i8** @addr
+    %val = load volatile i8*, i8** @addr
+    indirectbr i8* %val, [label %block]
+
+  block:
+    ret void
+  }
+
+...
+---
+name:            test
+body:
+  - id:              0
+    name:            entry
+    successors:      [ '%bb.1.block' ]
+    instructions:
+      # CHECK: [[@LINE+1]]:56: use of undefined IR block '%ir-block."block "'
+      - '%rax = LEA64r %rip, 1, _, blockaddress(@test, %ir-block."block "), _'
+      - 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
+      - 'JMP64m %rip, 1, _, @addr, _'
+  - id:              1
+    name:            block
+    addressTaken:    true
+    instructions:
+      - RETQ
+...

Added: llvm/trunk/test/CodeGen/MIR/X86/undefined-ir-block-slot-in-blockaddress.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/X86/undefined-ir-block-slot-in-blockaddress.mir?rev=243453&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/X86/undefined-ir-block-slot-in-blockaddress.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/X86/undefined-ir-block-slot-in-blockaddress.mir Tue Jul 28 12:28:03 2015
@@ -0,0 +1,32 @@
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+
+--- |
+
+  @addr = global i8* null
+
+  define void @test() {
+  entry:
+    store volatile i8* blockaddress(@test, %0), i8** @addr
+    %val = load volatile i8*, i8** @addr
+    indirectbr i8* %val, [label %0]
+
+    ret void
+  }
+
+...
+---
+name:            test
+body:
+  - id:              0
+    name:            entry
+    successors:      [ '%bb.1' ]
+    instructions:
+      # CHECK: [[@LINE+1]]:56: use of undefined IR block '%ir-block.1'
+      - '%rax = LEA64r %rip, 1, _, blockaddress(@test, %ir-block.1), _'
+      - 'MOV64mr %rip, 1, _, @addr, _, killed %rax'
+      - 'JMP64m %rip, 1, _, @addr, _'
+  - id:              1
+    addressTaken:    true
+    instructions:
+      - RETQ
+...





More information about the llvm-commits mailing list