summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MIRParser/MIParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/MIRParser/MIParser.cpp')
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.cpp225
1 files changed, 212 insertions, 13 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index fe979b981886..34e1f9225d42 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -395,6 +395,7 @@ class MIParser {
MachineFunction &MF;
SMDiagnostic &Error;
StringRef Source, CurrentSource;
+ SMRange SourceRange;
MIToken Token;
PerFunctionMIParsingState &PFS;
/// Maps from slot numbers to function's unnamed basic blocks.
@@ -403,6 +404,8 @@ class MIParser {
public:
MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
StringRef Source);
+ MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
+ StringRef Source, SMRange SourceRange);
/// \p SkipChar gives the number of characters to skip before looking
/// for the next token.
@@ -428,6 +431,10 @@ public:
bool parseStandaloneRegister(Register &Reg);
bool parseStandaloneStackObject(int &FI);
bool parseStandaloneMDNode(MDNode *&Node);
+ bool parseMachineMetadata();
+ bool parseMDTuple(MDNode *&MD, bool IsDistinct);
+ bool parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts);
+ bool parseMetadata(Metadata *&MD);
bool
parseBasicBlockDefinition(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
@@ -472,6 +479,7 @@ public:
bool parseMetadataOperand(MachineOperand &Dest);
bool parseCFIOffset(int &Offset);
bool parseCFIRegister(Register &Reg);
+ bool parseCFIAddressSpace(unsigned &AddressSpace);
bool parseCFIEscapeValues(std::string& Values);
bool parseCFIOperand(MachineOperand &Dest);
bool parseIRBlock(BasicBlock *&BB, const Function &F);
@@ -549,6 +557,10 @@ private:
/// parseStringConstant
/// ::= StringConstant
bool parseStringConstant(std::string &Result);
+
+ /// Map the location in the MI string to the corresponding location specified
+ /// in `SourceRange`.
+ SMLoc mapSMLoc(StringRef::iterator Loc);
};
} // end anonymous namespace
@@ -558,6 +570,11 @@ MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
: MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source), PFS(PFS)
{}
+MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
+ StringRef Source, SMRange SourceRange)
+ : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source),
+ SourceRange(SourceRange), PFS(PFS) {}
+
void MIParser::lex(unsigned SkipChar) {
CurrentSource = lexMIToken(
CurrentSource.slice(SkipChar, StringRef::npos), Token,
@@ -583,6 +600,13 @@ bool MIParser::error(StringRef::iterator Loc, const Twine &Msg) {
return true;
}
+SMLoc MIParser::mapSMLoc(StringRef::iterator Loc) {
+ assert(SourceRange.isValid() && "Invalid source range");
+ assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size()));
+ return SMLoc::getFromPointer(SourceRange.Start.getPointer() +
+ (Loc - Source.data()));
+}
+
typedef function_ref<bool(StringRef::iterator Loc, const Twine &)>
ErrorCallbackType;
@@ -987,7 +1011,9 @@ bool MIParser::parse(MachineInstr *&MI) {
Optional<unsigned> TiedDefIdx;
if (parseMachineOperandAndTargetFlags(OpCode, Operands.size(), MO, TiedDefIdx))
return true;
- if (OpCode == TargetOpcode::DBG_VALUE && MO.isReg())
+ if ((OpCode == TargetOpcode::DBG_VALUE ||
+ OpCode == TargetOpcode::DBG_VALUE_LIST) &&
+ MO.isReg())
MO.setIsDebug();
Operands.push_back(
ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx));
@@ -1168,6 +1194,130 @@ bool MIParser::parseStandaloneMDNode(MDNode *&Node) {
return false;
}
+bool MIParser::parseMachineMetadata() {
+ lex();
+ if (Token.isNot(MIToken::exclaim))
+ return error("expected a metadata node");
+
+ lex();
+ if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
+ return error("expected metadata id after '!'");
+ unsigned ID = 0;
+ if (getUnsigned(ID))
+ return true;
+ lex();
+ if (expectAndConsume(MIToken::equal))
+ return true;
+ bool IsDistinct = Token.is(MIToken::kw_distinct);
+ if (IsDistinct)
+ lex();
+ if (Token.isNot(MIToken::exclaim))
+ return error("expected a metadata node");
+ lex();
+
+ MDNode *MD;
+ if (parseMDTuple(MD, IsDistinct))
+ return true;
+
+ auto FI = PFS.MachineForwardRefMDNodes.find(ID);
+ if (FI != PFS.MachineForwardRefMDNodes.end()) {
+ FI->second.first->replaceAllUsesWith(MD);
+ PFS.MachineForwardRefMDNodes.erase(FI);
+
+ assert(PFS.MachineMetadataNodes[ID] == MD && "Tracking VH didn't work");
+ } else {
+ if (PFS.MachineMetadataNodes.count(ID))
+ return error("Metadata id is already used");
+ PFS.MachineMetadataNodes[ID].reset(MD);
+ }
+
+ return false;
+}
+
+bool MIParser::parseMDTuple(MDNode *&MD, bool IsDistinct) {
+ SmallVector<Metadata *, 16> Elts;
+ if (parseMDNodeVector(Elts))
+ return true;
+ MD = (IsDistinct ? MDTuple::getDistinct
+ : MDTuple::get)(MF.getFunction().getContext(), Elts);
+ return false;
+}
+
+bool MIParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
+ if (Token.isNot(MIToken::lbrace))
+ return error("expected '{' here");
+ lex();
+
+ if (Token.is(MIToken::rbrace)) {
+ lex();
+ return false;
+ }
+
+ do {
+ Metadata *MD;
+ if (parseMetadata(MD))
+ return true;
+
+ Elts.push_back(MD);
+
+ if (Token.isNot(MIToken::comma))
+ break;
+ lex();
+ } while (true);
+
+ if (Token.isNot(MIToken::rbrace))
+ return error("expected end of metadata node");
+ lex();
+
+ return false;
+}
+
+// ::= !42
+// ::= !"string"
+bool MIParser::parseMetadata(Metadata *&MD) {
+ if (Token.isNot(MIToken::exclaim))
+ return error("expected '!' here");
+ lex();
+
+ if (Token.is(MIToken::StringConstant)) {
+ std::string Str;
+ if (parseStringConstant(Str))
+ return true;
+ MD = MDString::get(MF.getFunction().getContext(), Str);
+ return false;
+ }
+
+ if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
+ return error("expected metadata id after '!'");
+
+ SMLoc Loc = mapSMLoc(Token.location());
+
+ unsigned ID = 0;
+ if (getUnsigned(ID))
+ return true;
+ lex();
+
+ auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID);
+ if (NodeInfo != PFS.IRSlots.MetadataNodes.end()) {
+ MD = NodeInfo->second.get();
+ return false;
+ }
+ // Check machine metadata.
+ NodeInfo = PFS.MachineMetadataNodes.find(ID);
+ if (NodeInfo != PFS.MachineMetadataNodes.end()) {
+ MD = NodeInfo->second.get();
+ return false;
+ }
+ // Forward reference.
+ auto &FwdRef = PFS.MachineForwardRefMDNodes[ID];
+ FwdRef = std::make_pair(
+ MDTuple::getTemporary(MF.getFunction().getContext(), None), Loc);
+ PFS.MachineMetadataNodes[ID].reset(FwdRef.first.get());
+ MD = FwdRef.first.get();
+
+ return false;
+}
+
static const char *printImplicitRegisterFlag(const MachineOperand &MO) {
assert(MO.isImplicit());
return MO.isDef() ? "implicit-def" : "implicit";
@@ -1726,7 +1876,7 @@ bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) {
return error(Loc, "expected <M x sN> or <M x pA> for vector type");
lex();
- Ty = LLT::vector(NumElements, Ty);
+ Ty = LLT::fixed_vector(NumElements, Ty);
return false;
}
@@ -2010,8 +2160,11 @@ bool MIParser::parseMDNode(MDNode *&Node) {
if (getUnsigned(ID))
return true;
auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID);
- if (NodeInfo == PFS.IRSlots.MetadataNodes.end())
- return error(Loc, "use of undefined metadata '!" + Twine(ID) + "'");
+ if (NodeInfo == PFS.IRSlots.MetadataNodes.end()) {
+ NodeInfo = PFS.MachineMetadataNodes.find(ID);
+ if (NodeInfo == PFS.MachineMetadataNodes.end())
+ return error(Loc, "use of undefined metadata '!" + Twine(ID) + "'");
+ }
lex();
Node = NodeInfo->second.get();
return false;
@@ -2205,6 +2358,16 @@ bool MIParser::parseCFIRegister(Register &Reg) {
return false;
}
+bool MIParser::parseCFIAddressSpace(unsigned &AddressSpace) {
+ if (Token.isNot(MIToken::IntegerLiteral))
+ return error("expected a cfi address space literal");
+ if (Token.integerValue().isSigned())
+ return error("expected an unsigned integer (cfi address space)");
+ AddressSpace = Token.integerValue().getZExtValue();
+ lex();
+ return false;
+}
+
bool MIParser::parseCFIEscapeValues(std::string &Values) {
do {
if (Token.isNot(MIToken::HexLiteral))
@@ -2225,6 +2388,7 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) {
lex();
int Offset;
Register Reg;
+ unsigned AddressSpace;
unsigned CFIIndex;
switch (Kind) {
case MIToken::kw_cfi_same_value:
@@ -2271,6 +2435,14 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) {
CFIIndex =
MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, Reg, Offset));
break;
+ case MIToken::kw_cfi_llvm_def_aspace_cfa:
+ if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
+ parseCFIOffset(Offset) || expectAndConsume(MIToken::comma) ||
+ parseCFIAddressSpace(AddressSpace))
+ return true;
+ CFIIndex = MF.addFrameInst(MCCFIInstruction::createLLVMDefAspaceCfa(
+ nullptr, Reg, Offset, AddressSpace));
+ break;
case MIToken::kw_cfi_remember_state:
CFIIndex = MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr));
break;
@@ -2618,6 +2790,7 @@ bool MIParser::parseMachineOperand(const unsigned OpCode, const unsigned OpIdx,
case MIToken::kw_cfi_adjust_cfa_offset:
case MIToken::kw_cfi_escape:
case MIToken::kw_cfi_def_cfa:
+ case MIToken::kw_cfi_llvm_def_aspace_cfa:
case MIToken::kw_cfi_register:
case MIToken::kw_cfi_remember_state:
case MIToken::kw_cfi_restore:
@@ -2788,6 +2961,9 @@ static bool parseIRValue(const MIToken &Token, PerFunctionMIParsingState &PFS,
V = C;
break;
}
+ case MIToken::kw_unknown_address:
+ V = nullptr;
+ return false;
default:
llvm_unreachable("The current token should be an IR block reference");
}
@@ -2948,12 +3124,13 @@ 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::QuotedIRValue))
+ Token.isNot(MIToken::QuotedIRValue) &&
+ Token.isNot(MIToken::kw_unknown_address))
return error("expected an IR value reference");
const Value *V = nullptr;
if (parseIRValue(V))
return true;
- if (!V->getType()->isPointerTy())
+ if (V && !V->getType()->isPointerTy())
return error("expected a pointer IR value");
lex();
int64_t Offset = 0;
@@ -3041,18 +3218,34 @@ bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) {
if (parseOptionalAtomicOrdering(FailureOrder))
return true;
+ LLT MemoryType;
if (Token.isNot(MIToken::IntegerLiteral) &&
- Token.isNot(MIToken::kw_unknown_size))
- return error("expected the size integer literal or 'unknown-size' after "
+ Token.isNot(MIToken::kw_unknown_size) &&
+ Token.isNot(MIToken::lparen))
+ return error("expected memory LLT, the size integer literal or 'unknown-size' after "
"memory operation");
- uint64_t Size;
+
+ uint64_t Size = MemoryLocation::UnknownSize;
if (Token.is(MIToken::IntegerLiteral)) {
if (getUint64(Size))
return true;
+
+ // Convert from bytes to bits for storage.
+ MemoryType = LLT::scalar(8 * Size);
+ lex();
} else if (Token.is(MIToken::kw_unknown_size)) {
Size = MemoryLocation::UnknownSize;
+ lex();
+ } else {
+ if (expectAndConsume(MIToken::lparen))
+ return true;
+ if (parseLowLevelType(Token.location(), MemoryType))
+ return true;
+ if (expectAndConsume(MIToken::rparen))
+ return true;
+
+ Size = MemoryType.getSizeInBytes();
}
- lex();
MachinePointerInfo Ptr = MachinePointerInfo();
if (Token.is(MIToken::Identifier)) {
@@ -3068,7 +3261,8 @@ bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) {
if (parseMachinePointerInfo(Ptr))
return true;
}
- unsigned BaseAlignment = (Size != MemoryLocation::UnknownSize ? Size : 1);
+ unsigned BaseAlignment =
+ (Size != MemoryLocation::UnknownSize ? PowerOf2Ceil(Size) : 1);
AAMDNodes AAInfo;
MDNode *Range = nullptr;
while (consumeIfPresent(MIToken::comma)) {
@@ -3115,8 +3309,8 @@ bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) {
}
if (expectAndConsume(MIToken::rparen))
return true;
- Dest = MF.getMachineMemOperand(Ptr, Flags, Size, Align(BaseAlignment), AAInfo,
- Range, SSID, Order, FailureOrder);
+ Dest = MF.getMachineMemOperand(Ptr, Flags, MemoryType, Align(BaseAlignment),
+ AAInfo, Range, SSID, Order, FailureOrder);
return false;
}
@@ -3252,6 +3446,11 @@ bool llvm::parseMDNode(PerFunctionMIParsingState &PFS,
return MIParser(PFS, Error, Src).parseStandaloneMDNode(Node);
}
+bool llvm::parseMachineMetadata(PerFunctionMIParsingState &PFS, StringRef Src,
+ SMRange SrcRange, SMDiagnostic &Error) {
+ return MIParser(PFS, Error, Src, SrcRange).parseMachineMetadata();
+}
+
bool MIRFormatter::parseIRValue(StringRef Src, MachineFunction &MF,
PerFunctionMIParsingState &PFS, const Value *&V,
ErrorCallbackType ErrorCallback) {