MIR Serialization: Serialize the block address machine operands.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243453 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Alex Lorenz 2015-07-28 17:28:03 +00:00
parent 6b43809281
commit 6d0376c00c
10 changed files with 373 additions and 4 deletions

View File

@ -147,6 +147,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.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(Cursor C, MIToken &Token) {
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(char C) {
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();

View File

@ -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.

View File

@ -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::TokenKind TokenKind) {
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(MachineOperand &Dest) {
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(MachineOperand &Dest) {
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:

View File

@ -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 MachineBasicBlock &MBB) {
}
}
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 MachineOperand &Op, const TargetRegisterInfo *TRI) {
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())

View File

@ -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
...

View File

@ -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
...

View File

@ -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
...

View File

@ -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
...

View File

@ -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
...

View File

@ -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
...