diff options
Diffstat (limited to 'llvm/lib/CodeGen/MIRParser/MIParser.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 225 |
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) { |
