MIR Serialization: Serialize the pointer IR expression values in the machine
memory operands. llvm-svn: 245745
This commit is contained in:
parent
366dd9fd2b
commit
c1136ef3b8
|
@ -527,6 +527,30 @@ static Cursor maybeLexNewline(Cursor C, MIToken &Token) {
|
|||
return C;
|
||||
}
|
||||
|
||||
static Cursor maybeLexEscapedIRValue(
|
||||
Cursor C, MIToken &Token,
|
||||
function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
|
||||
if (C.peek() != '`')
|
||||
return None;
|
||||
auto Range = C;
|
||||
C.advance();
|
||||
auto StrRange = C;
|
||||
while (C.peek() != '`') {
|
||||
if (C.isEOF() || isNewlineChar(C.peek())) {
|
||||
ErrorCallback(
|
||||
C.location(),
|
||||
"end of machine instruction reached before the closing '`'");
|
||||
Token.reset(MIToken::Error, Range.remaining());
|
||||
return C;
|
||||
}
|
||||
C.advance();
|
||||
}
|
||||
StringRef Value = StrRange.upto(C);
|
||||
C.advance();
|
||||
Token.reset(MIToken::QuotedIRValue, Range.upto(C)).setStringValue(Value);
|
||||
return C;
|
||||
}
|
||||
|
||||
StringRef llvm::lexMIToken(
|
||||
StringRef Source, MIToken &Token,
|
||||
function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
|
||||
|
@ -570,6 +594,8 @@ StringRef llvm::lexMIToken(
|
|||
return R.remaining();
|
||||
if (Cursor R = maybeLexNewline(C, Token))
|
||||
return R.remaining();
|
||||
if (Cursor R = maybeLexEscapedIRValue(C, Token, ErrorCallback))
|
||||
return R.remaining();
|
||||
|
||||
Token.reset(MIToken::Error, C.remaining());
|
||||
ErrorCallback(C.location(),
|
||||
|
|
|
@ -115,7 +115,8 @@ struct MIToken {
|
|||
NamedIRBlock,
|
||||
IRBlock,
|
||||
NamedIRValue,
|
||||
IRValue
|
||||
IRValue,
|
||||
QuotedIRValue // `<constant value>`
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -982,7 +982,8 @@ bool MIParser::parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
|
|||
const Constant *&C) {
|
||||
auto Source = StringValue.str(); // The source has to be null terminated.
|
||||
SMDiagnostic Err;
|
||||
C = parseConstantValue(Source.c_str(), Err, *MF.getFunction()->getParent());
|
||||
C = parseConstantValue(Source.c_str(), Err, *MF.getFunction()->getParent(),
|
||||
&IRSlots);
|
||||
if (!C)
|
||||
return error(Loc + Err.getColumnNo(), Err.getMessage());
|
||||
return false;
|
||||
|
@ -1557,6 +1558,13 @@ bool MIParser::parseIRValue(const Value *&V) {
|
|||
V = GV;
|
||||
break;
|
||||
}
|
||||
case MIToken::QuotedIRValue: {
|
||||
const Constant *C = nullptr;
|
||||
if (parseIRConstant(Token.location(), Token.stringValue(), C))
|
||||
return true;
|
||||
V = C;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
llvm_unreachable("The current token should be an IR block reference");
|
||||
}
|
||||
|
@ -1662,7 +1670,8 @@ bool MIParser::parseMachinePointerInfo(MachinePointerInfo &Dest) {
|
|||
}
|
||||
if (Token.isNot(MIToken::NamedIRValue) && Token.isNot(MIToken::IRValue) &&
|
||||
Token.isNot(MIToken::GlobalValue) &&
|
||||
Token.isNot(MIToken::NamedGlobalValue))
|
||||
Token.isNot(MIToken::NamedGlobalValue) &&
|
||||
Token.isNot(MIToken::QuotedIRValue))
|
||||
return error("expected an IR value reference");
|
||||
const Value *V = nullptr;
|
||||
if (parseIRValue(V))
|
||||
|
|
|
@ -613,17 +613,18 @@ void MIPrinter::printIRValueReference(const Value &V) {
|
|||
V.printAsOperand(OS, /*PrintType=*/false, MST);
|
||||
return;
|
||||
}
|
||||
if (isa<Constant>(V)) {
|
||||
// Machine memory operands can load/store to/from constant value pointers.
|
||||
OS << '`';
|
||||
V.printAsOperand(OS, /*PrintType=*/true, MST);
|
||||
OS << '`';
|
||||
return;
|
||||
}
|
||||
OS << "%ir.";
|
||||
if (V.hasName()) {
|
||||
printLLVMNameWithoutPrefix(OS, V.getName());
|
||||
return;
|
||||
}
|
||||
if (isa<Constant>(V)) {
|
||||
// Machine memory operands can load/store to/from constant value pointers.
|
||||
// TODO: Serialize the constant values.
|
||||
OS << "<unserializable ir value>";
|
||||
return;
|
||||
}
|
||||
printIRSlotNumber(OS, MST.getLocalSlot(&V));
|
||||
}
|
||||
|
||||
|
|
|
@ -170,6 +170,16 @@
|
|||
|
||||
!11 = !{i8 0, i8 2}
|
||||
|
||||
%st = type { i32, i32 }
|
||||
|
||||
@values = common global [50 x %st] zeroinitializer, align 16
|
||||
|
||||
define void @gep_value(i64 %d) {
|
||||
entry:
|
||||
%conv = trunc i64 %d to i32
|
||||
store i32 %conv, i32* getelementptr inbounds ([50 x %st], [50 x %st]* @values, i64 0, i64 0, i32 0), align 16
|
||||
ret void
|
||||
}
|
||||
...
|
||||
---
|
||||
name: test
|
||||
|
@ -465,3 +475,18 @@ body: |
|
|||
%al = MOV8rm killed %rdi, 1, _, 0, _ :: (load 1 from %ir.x, !range !11)
|
||||
RETQ %al
|
||||
...
|
||||
---
|
||||
name: gep_value
|
||||
tracksRegLiveness: true
|
||||
liveins:
|
||||
- { reg: '%rdi' }
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: %rdi
|
||||
|
||||
%rax = MOV64rm %rip, 1, _, @values, _ :: (load 8 from got)
|
||||
; CHECK-LABEL: gep_value
|
||||
; CHECK: MOV32mr killed %rax, 1, _, 0, _, %edi, implicit killed %rdi :: (store 4 into `i32* getelementptr inbounds ([50 x %st], [50 x %st]* @values, i64 0, i64 0, i32 0)`, align 16)
|
||||
MOV32mr killed %rax, 1, _, 0, _, %edi, implicit killed %rdi :: (store 4 into `i32* getelementptr inbounds ([50 x %st], [50 x %st]* @values, i64 0, i64 0, i32 0)`, align 16)
|
||||
RETQ
|
||||
...
|
||||
|
|
|
@ -12,6 +12,6 @@
|
|||
name: foo
|
||||
body: |
|
||||
bb.0.entry:
|
||||
; CHECK: [[@LINE+1]]:5: unexpected character '`'
|
||||
` RETQ
|
||||
; CHECK: [[@LINE+1]]:5: unexpected character '\'
|
||||
\ RETQ
|
||||
...
|
||||
|
|
Loading…
Reference in New Issue