forked from OSchip/llvm-project
[MIR] Teach the parser how to parse complex types of generic machine instructions.
By complex types, I mean aggregate or vector types. llvm-svn: 262890
This commit is contained in:
parent
89e9597a50
commit
287c6bb571
|
@ -497,6 +497,10 @@ static MIToken::TokenKind symbolToken(char C) {
|
|||
return MIToken::plus;
|
||||
case '-':
|
||||
return MIToken::minus;
|
||||
case '<':
|
||||
return MIToken::lt;
|
||||
case '>':
|
||||
return MIToken::gt;
|
||||
default:
|
||||
return MIToken::Error;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@ struct MIToken {
|
|||
rbrace,
|
||||
plus,
|
||||
minus,
|
||||
lt,
|
||||
gt,
|
||||
|
||||
// Keywords
|
||||
kw_implicit,
|
||||
|
|
|
@ -88,7 +88,9 @@ public:
|
|||
StringRef Source, const PerFunctionMIParsingState &PFS,
|
||||
const SlotMapping &IRSlots);
|
||||
|
||||
void lex();
|
||||
/// \p SkipChar gives the number of characters to skip before looking
|
||||
/// for the next token.
|
||||
void lex(unsigned SkipChar = 0);
|
||||
|
||||
/// Report an error at the current location with the given message.
|
||||
///
|
||||
|
@ -127,8 +129,10 @@ public:
|
|||
bool parseIRConstant(StringRef::iterator Loc, StringRef Source,
|
||||
const Constant *&C);
|
||||
bool parseIRConstant(StringRef::iterator Loc, const Constant *&C);
|
||||
bool parseIRType(StringRef::iterator Loc, StringRef Source, Type *&Ty);
|
||||
bool parseIRType(StringRef::iterator Loc, Type *&Ty);
|
||||
bool parseIRType(StringRef::iterator Loc, StringRef Source, unsigned &Read,
|
||||
Type *&Ty);
|
||||
// \p MustBeSized defines whether or not \p Ty must be sized.
|
||||
bool parseIRType(StringRef::iterator Loc, Type *&Ty, bool MustBeSized = true);
|
||||
bool parseTypedImmediateOperand(MachineOperand &Dest);
|
||||
bool parseFPImmediateOperand(MachineOperand &Dest);
|
||||
bool parseMBBReference(MachineBasicBlock *&MBB);
|
||||
|
@ -254,9 +258,9 @@ MIParser::MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error,
|
|||
: SM(SM), MF(MF), Error(Error), Source(Source), CurrentSource(Source),
|
||||
PFS(PFS), IRSlots(IRSlots) {}
|
||||
|
||||
void MIParser::lex() {
|
||||
void MIParser::lex(unsigned SkipChar) {
|
||||
CurrentSource = lexMIToken(
|
||||
CurrentSource, Token,
|
||||
CurrentSource.data() + SkipChar, Token,
|
||||
[this](StringRef::iterator Loc, const Twine &Msg) { error(Loc, Msg); });
|
||||
}
|
||||
|
||||
|
@ -597,10 +601,6 @@ bool MIParser::parse(MachineInstr *&MI) {
|
|||
auto Loc = Token.location();
|
||||
if (parseIRType(Loc, Ty))
|
||||
return true;
|
||||
// The type must be sized, otherwise there is not much the backend
|
||||
// can do with it.
|
||||
if (!Ty->isSized())
|
||||
return error("expected a fully defined type for generic instruction");
|
||||
}
|
||||
|
||||
// Parse the remaining machine operands.
|
||||
|
@ -1019,19 +1019,34 @@ bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) {
|
|||
}
|
||||
|
||||
bool MIParser::parseIRType(StringRef::iterator Loc, StringRef StringValue,
|
||||
Type *&Ty) {
|
||||
unsigned &Read, Type *&Ty) {
|
||||
auto Source = StringValue.str(); // The source has to be null terminated.
|
||||
SMDiagnostic Err;
|
||||
Ty = parseType(Source.c_str(), Err, *MF.getFunction()->getParent(), &IRSlots);
|
||||
Ty = parseTypeAtBeginning(Source.c_str(), Read, Err,
|
||||
*MF.getFunction()->getParent(), &IRSlots);
|
||||
if (!Ty)
|
||||
return error(Loc + Err.getColumnNo(), Err.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MIParser::parseIRType(StringRef::iterator Loc, Type *&Ty) {
|
||||
if (parseIRType(Loc, StringRef(Loc, Token.range().end() - Loc), Ty))
|
||||
bool MIParser::parseIRType(StringRef::iterator Loc, Type *&Ty,
|
||||
bool MustBeSized) {
|
||||
// At this point we enter in the IR world, i.e., to get the correct type,
|
||||
// we need to hand off the whole string, not just the current token.
|
||||
// E.g., <4 x i64> would give '<' as a token and there is not much
|
||||
// the IR parser can do with that.
|
||||
unsigned Read = 0;
|
||||
if (parseIRType(Loc, StringRef(Loc), Read, Ty))
|
||||
return true;
|
||||
lex();
|
||||
// The type must be sized, otherwise there is not much the backend
|
||||
// can do with it.
|
||||
if (MustBeSized && !Ty->isSized())
|
||||
return error("expected a sized type");
|
||||
// The next token is Read characters from the Loc.
|
||||
// However, the current location is not Loc, but Loc + the length of Token.
|
||||
// Therefore, subtract the length of Token (range().end() - Loc) to the
|
||||
// number of characters to skip before the next token.
|
||||
lex(Read - (Token.range().end() - Loc));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,16 +3,43 @@
|
|||
# This test ensures that the MIR parser parses generic virtual
|
||||
# register definitions correctly.
|
||||
|
||||
--- |
|
||||
; ModuleID = 'generic-virtual-registers-type-error.mir'
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
%type_alias = type <2 x i32>
|
||||
%structure_alias = type { i32, i16 }
|
||||
define void @bar() {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
---
|
||||
name: bar
|
||||
isSSA: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gr32 }
|
||||
# CHECK-NEXT: - { id: 1, class: gr64 }
|
||||
registers:
|
||||
- { id: 0, class: gr32 }
|
||||
- { id: 1, class: gr64 }
|
||||
- { id: 2, class: gr64 }
|
||||
- { id: 3, class: gr64 }
|
||||
- { id: 4, class: gr64 }
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: %edi
|
||||
; CHECK: %0(32) = G_ADD i32 %edi
|
||||
%0(32) = G_ADD i32 %edi, %edi
|
||||
; CHECK: %1(64) = G_ADD <2 x i32> %edi
|
||||
%1(64) = G_ADD <2 x i32> %edi, %edi
|
||||
; CHECK: %2(64) = G_ADD <2 x i32> %edi
|
||||
%2(64) = G_ADD %type_alias %edi, %edi
|
||||
; G_ADD is actually not a valid operand for structure type,
|
||||
; but that is the only one we have for now for testing.
|
||||
; CHECK: %3(64) = G_ADD { i32, i32 } %edi
|
||||
%3(64) = G_ADD {i32, i32} %edi, %edi
|
||||
; CHECK: %4(48) = G_ADD %structure_alias %edi
|
||||
%4(48) = G_ADD %structure_alias %edi, %edi
|
||||
...
|
||||
|
|
Loading…
Reference in New Issue