mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-26 22:45:05 +00:00
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:
parent
6b43809281
commit
6d0376c00c
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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())
|
||||
|
89
test/CodeGen/MIR/X86/block-address-operands.mir
Normal file
89
test/CodeGen/MIR/X86/block-address-operands.mir
Normal 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
|
||||
...
|
@ -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
|
||||
...
|
@ -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
|
||||
...
|
@ -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
|
||||
...
|
34
test/CodeGen/MIR/X86/undefined-ir-block-in-blockaddress.mir
Normal file
34
test/CodeGen/MIR/X86/undefined-ir-block-in-blockaddress.mir
Normal 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
|
||||
...
|
@ -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
|
||||
...
|
Loading…
x
Reference in New Issue
Block a user