summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MIRParser
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
commit706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch)
tree4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/CodeGen/MIRParser
parent7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff)
Notes
Diffstat (limited to 'llvm/lib/CodeGen/MIRParser')
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.cpp10
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.h4
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.cpp326
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIRParser.cpp45
4 files changed, 262 insertions, 123 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
index ad5c617623f2..5976f5da1569 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -204,7 +204,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("nuw" , MIToken::kw_nuw)
.Case("nsw" , MIToken::kw_nsw)
.Case("exact" , MIToken::kw_exact)
- .Case("fpexcept", MIToken::kw_fpexcept)
+ .Case("nofpexcept", MIToken::kw_nofpexcept)
.Case("debug-location", MIToken::kw_debug_location)
.Case("same_value", MIToken::kw_cfi_same_value)
.Case("offset", MIToken::kw_cfi_offset)
@@ -242,6 +242,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("jump-table", MIToken::kw_jump_table)
.Case("constant-pool", MIToken::kw_constant_pool)
.Case("call-entry", MIToken::kw_call_entry)
+ .Case("custom", MIToken::kw_custom)
.Case("liveout", MIToken::kw_liveout)
.Case("address-taken", MIToken::kw_address_taken)
.Case("landing-pad", MIToken::kw_landing_pad)
@@ -252,6 +253,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("shufflemask", MIToken::kw_shufflemask)
.Case("pre-instr-symbol", MIToken::kw_pre_instr_symbol)
.Case("post-instr-symbol", MIToken::kw_post_instr_symbol)
+ .Case("heap-alloc-marker", MIToken::kw_heap_alloc_marker)
.Case("unknown-size", MIToken::kw_unknown_size)
.Default(MIToken::Identifier);
}
@@ -582,8 +584,8 @@ static MIToken::TokenKind getMetadataKeywordKind(StringRef Identifier) {
.Default(MIToken::Error);
}
-static Cursor maybeLexExlaim(Cursor C, MIToken &Token,
- ErrorCallbackType ErrorCallback) {
+static Cursor maybeLexExclaim(Cursor C, MIToken &Token,
+ ErrorCallbackType ErrorCallback) {
if (C.peek() != '!')
return None;
auto Range = C;
@@ -719,7 +721,7 @@ StringRef llvm::lexMIToken(StringRef Source, MIToken &Token,
return R.remaining();
if (Cursor R = maybeLexNumericalLiteral(C, Token))
return R.remaining();
- if (Cursor R = maybeLexExlaim(C, Token, ErrorCallback))
+ if (Cursor R = maybeLexExclaim(C, Token, ErrorCallback))
return R.remaining();
if (Cursor R = maybeLexSymbol(C, Token))
return R.remaining();
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h
index 200f9d026cc8..aaffe4a4c91b 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.h
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -73,7 +73,7 @@ struct MIToken {
kw_nuw,
kw_nsw,
kw_exact,
- kw_fpexcept,
+ kw_nofpexcept,
kw_debug_location,
kw_cfi_same_value,
kw_cfi_offset,
@@ -110,6 +110,7 @@ struct MIToken {
kw_jump_table,
kw_constant_pool,
kw_call_entry,
+ kw_custom,
kw_liveout,
kw_address_taken,
kw_landing_pad,
@@ -120,6 +121,7 @@ struct MIToken {
kw_shufflemask,
kw_pre_instr_symbol,
kw_post_instr_symbol,
+ kw_heap_alloc_marker,
kw_unknown_size,
// Named metadata keywords
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 6498acc9fa51..076ca943788b 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -28,6 +28,7 @@
#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
+#include "llvm/CodeGen/MIRFormatter.h"
#include "llvm/CodeGen/MIRPrinter.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -343,6 +344,37 @@ VRegInfo &PerFunctionMIParsingState::getVRegInfoNamed(StringRef RegName) {
return *I.first->second;
}
+static void mapValueToSlot(const Value *V, ModuleSlotTracker &MST,
+ DenseMap<unsigned, const Value *> &Slots2Values) {
+ int Slot = MST.getLocalSlot(V);
+ if (Slot == -1)
+ return;
+ Slots2Values.insert(std::make_pair(unsigned(Slot), V));
+}
+
+/// Creates the mapping from slot numbers to function's unnamed IR values.
+static void initSlots2Values(const Function &F,
+ DenseMap<unsigned, const Value *> &Slots2Values) {
+ ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
+ MST.incorporateFunction(F);
+ for (const auto &Arg : F.args())
+ mapValueToSlot(&Arg, MST, Slots2Values);
+ for (const auto &BB : F) {
+ mapValueToSlot(&BB, MST, Slots2Values);
+ for (const auto &I : BB)
+ mapValueToSlot(&I, MST, Slots2Values);
+ }
+}
+
+const Value* PerFunctionMIParsingState::getIRValue(unsigned Slot) {
+ if (Slots2Values.empty())
+ initSlots2Values(MF.getFunction(), Slots2Values);
+ auto ValueInfo = Slots2Values.find(Slot);
+ if (ValueInfo == Slots2Values.end())
+ return nullptr;
+ return ValueInfo->second;
+}
+
namespace {
/// A wrapper struct around the 'MachineOperand' struct that includes a source
@@ -370,8 +402,6 @@ class MIParser {
PerFunctionMIParsingState &PFS;
/// Maps from slot numbers to function's unnamed basic blocks.
DenseMap<unsigned, const BasicBlock *> Slots2BasicBlocks;
- /// Maps from slot numbers to function's unnamed values.
- DenseMap<unsigned, const Value *> Slots2Values;
public:
MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
@@ -455,9 +485,12 @@ public:
bool parseTargetIndexOperand(MachineOperand &Dest);
bool parseCustomRegisterMaskOperand(MachineOperand &Dest);
bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest);
- bool parseMachineOperand(MachineOperand &Dest,
+ bool parseMachineOperand(const unsigned OpCode, const unsigned OpIdx,
+ MachineOperand &Dest,
Optional<unsigned> &TiedDefIdx);
- bool parseMachineOperandAndTargetFlags(MachineOperand &Dest,
+ bool parseMachineOperandAndTargetFlags(const unsigned OpCode,
+ const unsigned OpIdx,
+ MachineOperand &Dest,
Optional<unsigned> &TiedDefIdx);
bool parseOffset(int64_t &Offset);
bool parseAlignment(unsigned &Alignment);
@@ -471,6 +504,10 @@ public:
bool parseOptionalAtomicOrdering(AtomicOrdering &Order);
bool parseMachineMemoryOperand(MachineMemOperand *&Dest);
bool parsePreOrPostInstrSymbol(MCSymbol *&Symbol);
+ bool parseHeapAllocMarker(MDNode *&Node);
+
+ bool parseTargetImmMnemonic(const unsigned OpCode, const unsigned OpIdx,
+ MachineOperand &Dest, const MIRFormatter &MF);
private:
/// Convert the integer literal in the current token into an unsigned integer.
@@ -508,8 +545,6 @@ private:
const BasicBlock *getIRBlock(unsigned Slot);
const BasicBlock *getIRBlock(unsigned Slot, const Function &F);
- const Value *getIRValue(unsigned Slot);
-
/// Get or create an MCSymbol for a given name.
MCSymbol *getOrCreateMCSymbol(StringRef Name);
@@ -550,6 +585,9 @@ bool MIParser::error(StringRef::iterator Loc, const Twine &Msg) {
return true;
}
+typedef function_ref<bool(StringRef::iterator Loc, const Twine &)>
+ ErrorCallbackType;
+
static const char *toString(MIToken::TokenKind TokenKind) {
switch (TokenKind) {
case MIToken::comma:
@@ -906,11 +944,12 @@ bool MIParser::parse(MachineInstr *&MI) {
// Parse the remaining machine operands.
while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_pre_instr_symbol) &&
Token.isNot(MIToken::kw_post_instr_symbol) &&
+ Token.isNot(MIToken::kw_heap_alloc_marker) &&
Token.isNot(MIToken::kw_debug_location) &&
Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) {
auto Loc = Token.location();
Optional<unsigned> TiedDefIdx;
- if (parseMachineOperandAndTargetFlags(MO, TiedDefIdx))
+ if (parseMachineOperandAndTargetFlags(OpCode, Operands.size(), MO, TiedDefIdx))
return true;
if (OpCode == TargetOpcode::DBG_VALUE && MO.isReg())
MO.setIsDebug();
@@ -932,6 +971,10 @@ bool MIParser::parse(MachineInstr *&MI) {
if (Token.is(MIToken::kw_post_instr_symbol))
if (parsePreOrPostInstrSymbol(PostInstrSymbol))
return true;
+ MDNode *HeapAllocMarker = nullptr;
+ if (Token.is(MIToken::kw_heap_alloc_marker))
+ if (parseHeapAllocMarker(HeapAllocMarker))
+ return true;
DebugLoc DebugLocation;
if (Token.is(MIToken::kw_debug_location)) {
@@ -985,6 +1028,8 @@ bool MIParser::parse(MachineInstr *&MI) {
MI->setPreInstrSymbol(MF, PreInstrSymbol);
if (PostInstrSymbol)
MI->setPostInstrSymbol(MF, PostInstrSymbol);
+ if (HeapAllocMarker)
+ MI->setHeapAllocMarker(MF, HeapAllocMarker);
if (!MemOperands.empty())
MI->setMemRefs(MF, MemOperands);
return false;
@@ -1138,7 +1183,7 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
Token.is(MIToken::kw_nuw) ||
Token.is(MIToken::kw_nsw) ||
Token.is(MIToken::kw_exact) ||
- Token.is(MIToken::kw_fpexcept)) {
+ Token.is(MIToken::kw_nofpexcept)) {
// Mine frame and fast math flags
if (Token.is(MIToken::kw_frame_setup))
Flags |= MachineInstr::FrameSetup;
@@ -1164,8 +1209,8 @@ bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
Flags |= MachineInstr::NoSWrap;
if (Token.is(MIToken::kw_exact))
Flags |= MachineInstr::IsExact;
- if (Token.is(MIToken::kw_fpexcept))
- Flags |= MachineInstr::FPExcept;
+ if (Token.is(MIToken::kw_nofpexcept))
+ Flags |= MachineInstr::NoFPExcept;
lex();
}
@@ -1485,17 +1530,61 @@ bool MIParser::parseImmediateOperand(MachineOperand &Dest) {
return false;
}
-bool MIParser::parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
- const Constant *&C) {
+bool MIParser::parseTargetImmMnemonic(const unsigned OpCode,
+ const unsigned OpIdx,
+ MachineOperand &Dest,
+ const MIRFormatter &MF) {
+ assert(Token.is(MIToken::dot));
+ auto Loc = Token.location(); // record start position
+ size_t Len = 1; // for "."
+ lex();
+
+ // Handle the case that mnemonic starts with number.
+ if (Token.is(MIToken::IntegerLiteral)) {
+ Len += Token.range().size();
+ lex();
+ }
+
+ StringRef Src;
+ if (Token.is(MIToken::comma))
+ Src = StringRef(Loc, Len);
+ else {
+ assert(Token.is(MIToken::Identifier));
+ Src = StringRef(Loc, Len + Token.stringValue().size());
+ }
+ int64_t Val;
+ if (MF.parseImmMnemonic(OpCode, OpIdx, Src, Val,
+ [this](StringRef::iterator Loc, const Twine &Msg)
+ -> bool { return error(Loc, Msg); }))
+ return true;
+
+ Dest = MachineOperand::CreateImm(Val);
+ if (!Token.is(MIToken::comma))
+ lex();
+ return false;
+}
+
+static bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
+ PerFunctionMIParsingState &PFS, const Constant *&C,
+ ErrorCallbackType ErrCB) {
auto Source = StringValue.str(); // The source has to be null terminated.
SMDiagnostic Err;
- C = parseConstantValue(Source, Err, *MF.getFunction().getParent(),
+ C = parseConstantValue(Source, Err, *PFS.MF.getFunction().getParent(),
&PFS.IRSlots);
if (!C)
- return error(Loc + Err.getColumnNo(), Err.getMessage());
+ return ErrCB(Loc + Err.getColumnNo(), Err.getMessage());
return false;
}
+bool MIParser::parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
+ const Constant *&C) {
+ return ::parseIRConstant(
+ Loc, StringValue, PFS, C,
+ [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
+ return error(Loc, Msg);
+ });
+}
+
bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) {
if (parseIRConstant(Loc, StringRef(Loc, Token.range().end() - Loc), C))
return true;
@@ -1628,27 +1717,52 @@ bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) {
return false;
}
-bool MIParser::getUnsigned(unsigned &Result) {
+static bool getHexUint(const MIToken &Token, APInt &Result) {
+ assert(Token.is(MIToken::HexLiteral));
+ StringRef S = Token.range();
+ assert(S[0] == '0' && tolower(S[1]) == 'x');
+ // This could be a floating point literal with a special prefix.
+ if (!isxdigit(S[2]))
+ return true;
+ StringRef V = S.substr(2);
+ APInt A(V.size()*4, V, 16);
+
+ // If A is 0, then A.getActiveBits() is 0. This isn't a valid bitwidth. Make
+ // sure it isn't the case before constructing result.
+ unsigned NumBits = (A == 0) ? 32 : A.getActiveBits();
+ Result = APInt(NumBits, ArrayRef<uint64_t>(A.getRawData(), A.getNumWords()));
+ return false;
+}
+
+static bool getUnsigned(const MIToken &Token, unsigned &Result,
+ ErrorCallbackType ErrCB) {
if (Token.hasIntegerValue()) {
const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1;
uint64_t Val64 = Token.integerValue().getLimitedValue(Limit);
if (Val64 == Limit)
- return error("expected 32-bit integer (too large)");
+ return ErrCB(Token.location(), "expected 32-bit integer (too large)");
Result = Val64;
return false;
}
if (Token.is(MIToken::HexLiteral)) {
APInt A;
- if (getHexUint(A))
+ if (getHexUint(Token, A))
return true;
if (A.getBitWidth() > 32)
- return error("expected 32-bit integer (too large)");
+ return ErrCB(Token.location(), "expected 32-bit integer (too large)");
Result = A.getZExtValue();
return false;
}
return true;
}
+bool MIParser::getUnsigned(unsigned &Result) {
+ return ::getUnsigned(
+ Token, Result, [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
+ return error(Loc, Msg);
+ });
+}
+
bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) {
assert(Token.is(MIToken::MachineBasicBlock) ||
Token.is(MIToken::MachineBasicBlockLabel));
@@ -1728,23 +1842,25 @@ bool MIParser::parseFixedStackObjectOperand(MachineOperand &Dest) {
return false;
}
-bool MIParser::parseGlobalValue(GlobalValue *&GV) {
+static bool parseGlobalValue(const MIToken &Token,
+ PerFunctionMIParsingState &PFS, GlobalValue *&GV,
+ ErrorCallbackType ErrCB) {
switch (Token.kind()) {
case MIToken::NamedGlobalValue: {
- const Module *M = MF.getFunction().getParent();
+ const Module *M = PFS.MF.getFunction().getParent();
GV = M->getNamedValue(Token.stringValue());
if (!GV)
- return error(Twine("use of undefined global value '") + Token.range() +
- "'");
+ return ErrCB(Token.location(), Twine("use of undefined global value '") +
+ Token.range() + "'");
break;
}
case MIToken::GlobalValue: {
unsigned GVIdx;
- if (getUnsigned(GVIdx))
+ if (getUnsigned(Token, GVIdx, ErrCB))
return true;
if (GVIdx >= PFS.IRSlots.GlobalValues.size())
- return error(Twine("use of undefined global value '@") + Twine(GVIdx) +
- "'");
+ return ErrCB(Token.location(), Twine("use of undefined global value '@") +
+ Twine(GVIdx) + "'");
GV = PFS.IRSlots.GlobalValues[GVIdx];
break;
}
@@ -1754,6 +1870,14 @@ bool MIParser::parseGlobalValue(GlobalValue *&GV) {
return false;
}
+bool MIParser::parseGlobalValue(GlobalValue *&GV) {
+ return ::parseGlobalValue(
+ Token, PFS, GV,
+ [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
+ return error(Loc, Msg);
+ });
+}
+
bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) {
GlobalValue *GV = nullptr;
if (parseGlobalValue(GV))
@@ -2295,23 +2419,13 @@ bool MIParser::parseShuffleMaskOperand(MachineOperand &Dest) {
if (expectAndConsume(MIToken::lparen))
return error("expected syntax shufflemask(<integer or undef>, ...)");
- SmallVector<Constant *, 32> ShufMask;
- LLVMContext &Ctx = MF.getFunction().getContext();
- Type *I32Ty = Type::getInt32Ty(Ctx);
-
- bool AllZero = true;
- bool AllUndef = true;
-
+ SmallVector<int, 32> ShufMask;
do {
if (Token.is(MIToken::kw_undef)) {
- ShufMask.push_back(UndefValue::get(I32Ty));
- AllZero = false;
+ ShufMask.push_back(-1);
} else if (Token.is(MIToken::IntegerLiteral)) {
- AllUndef = false;
const APSInt &Int = Token.integerValue();
- if (!Int.isNullValue())
- AllZero = false;
- ShufMask.push_back(ConstantInt::get(I32Ty, Int.getExtValue()));
+ ShufMask.push_back(Int.getExtValue());
} else
return error("expected integer constant");
@@ -2321,13 +2435,8 @@ bool MIParser::parseShuffleMaskOperand(MachineOperand &Dest) {
if (expectAndConsume(MIToken::rparen))
return error("shufflemask should be terminated by ')'.");
- if (AllZero || AllUndef) {
- VectorType *VT = VectorType::get(I32Ty, ShufMask.size());
- Constant *C = AllZero ? Constant::getNullValue(VT) : UndefValue::get(VT);
- Dest = MachineOperand::CreateShuffleMask(C);
- } else
- Dest = MachineOperand::CreateShuffleMask(ConstantVector::get(ShufMask));
-
+ ArrayRef<int> MaskAlloc = MF.allocateShuffleMask(ShufMask);
+ Dest = MachineOperand::CreateShuffleMask(MaskAlloc);
return false;
}
@@ -2402,7 +2511,8 @@ bool MIParser::parseLiveoutRegisterMaskOperand(MachineOperand &Dest) {
return false;
}
-bool MIParser::parseMachineOperand(MachineOperand &Dest,
+bool MIParser::parseMachineOperand(const unsigned OpCode, const unsigned OpIdx,
+ MachineOperand &Dest,
Optional<unsigned> &TiedDefIdx) {
switch (Token.kind()) {
case MIToken::kw_implicit:
@@ -2491,6 +2601,13 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest,
return parseCustomRegisterMaskOperand(Dest);
} else
return parseTypedImmediateOperand(Dest);
+ case MIToken::dot: {
+ const auto *TII = MF.getSubtarget().getInstrInfo();
+ if (const auto *Formatter = TII->getMIRFormatter()) {
+ return parseTargetImmMnemonic(OpCode, OpIdx, Dest, *Formatter);
+ }
+ LLVM_FALLTHROUGH;
+ }
default:
// FIXME: Parse the MCSymbol machine operand.
return error("expected a machine operand");
@@ -2499,7 +2616,8 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest,
}
bool MIParser::parseMachineOperandAndTargetFlags(
- MachineOperand &Dest, Optional<unsigned> &TiedDefIdx) {
+ const unsigned OpCode, const unsigned OpIdx, MachineOperand &Dest,
+ Optional<unsigned> &TiedDefIdx) {
unsigned TF = 0;
bool HasTargetFlags = false;
if (Token.is(MIToken::kw_target_flags)) {
@@ -2531,7 +2649,7 @@ bool MIParser::parseMachineOperandAndTargetFlags(
return true;
}
auto Loc = Token.location();
- if (parseMachineOperand(Dest, TiedDefIdx))
+ if (parseMachineOperand(OpCode, OpIdx, Dest, TiedDefIdx))
return true;
if (!HasTargetFlags)
return false;
@@ -2592,30 +2710,31 @@ bool MIParser::parseOperandsOffset(MachineOperand &Op) {
return false;
}
-bool MIParser::parseIRValue(const Value *&V) {
+static bool parseIRValue(const MIToken &Token, PerFunctionMIParsingState &PFS,
+ const Value *&V, ErrorCallbackType ErrCB) {
switch (Token.kind()) {
case MIToken::NamedIRValue: {
- V = MF.getFunction().getValueSymbolTable()->lookup(Token.stringValue());
+ V = PFS.MF.getFunction().getValueSymbolTable()->lookup(Token.stringValue());
break;
}
case MIToken::IRValue: {
unsigned SlotNumber = 0;
- if (getUnsigned(SlotNumber))
+ if (getUnsigned(Token, SlotNumber, ErrCB))
return true;
- V = getIRValue(SlotNumber);
+ V = PFS.getIRValue(SlotNumber);
break;
}
case MIToken::NamedGlobalValue:
case MIToken::GlobalValue: {
GlobalValue *GV = nullptr;
- if (parseGlobalValue(GV))
+ if (parseGlobalValue(Token, PFS, GV, ErrCB))
return true;
V = GV;
break;
}
case MIToken::QuotedIRValue: {
const Constant *C = nullptr;
- if (parseIRConstant(Token.location(), Token.stringValue(), C))
+ if (parseIRConstant(Token.location(), Token.stringValue(), PFS, C, ErrCB))
return true;
V = C;
break;
@@ -2624,10 +2743,17 @@ bool MIParser::parseIRValue(const Value *&V) {
llvm_unreachable("The current token should be an IR block reference");
}
if (!V)
- return error(Twine("use of undefined IR value '") + Token.range() + "'");
+ return ErrCB(Token.location(), Twine("use of undefined IR value '") + Token.range() + "'");
return false;
}
+bool MIParser::parseIRValue(const Value *&V) {
+ return ::parseIRValue(
+ Token, PFS, V, [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
+ return error(Loc, Msg);
+ });
+}
+
bool MIParser::getUint64(uint64_t &Result) {
if (Token.hasIntegerValue()) {
if (Token.integerValue().getActiveBits() > 64)
@@ -2648,20 +2774,7 @@ bool MIParser::getUint64(uint64_t &Result) {
}
bool MIParser::getHexUint(APInt &Result) {
- assert(Token.is(MIToken::HexLiteral));
- StringRef S = Token.range();
- assert(S[0] == '0' && tolower(S[1]) == 'x');
- // This could be a floating point literal with a special prefix.
- if (!isxdigit(S[2]))
- return true;
- StringRef V = S.substr(2);
- APInt A(V.size()*4, V, 16);
-
- // If A is 0, then A.getActiveBits() is 0. This isn't a valid bitwidth. Make
- // sure it isn't the case before constructing result.
- unsigned NumBits = (A == 0) ? 32 : A.getActiveBits();
- Result = APInt(NumBits, ArrayRef<uint64_t>(A.getRawData(), A.getNumWords()));
- return false;
+ return ::getHexUint(Token, Result);
}
bool MIParser::parseMemoryOperandFlag(MachineMemOperand::Flags &Flags) {
@@ -2748,6 +2861,20 @@ bool MIParser::parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV) {
"expected a global value or an external symbol after 'call-entry'");
}
break;
+ case MIToken::kw_custom: {
+ lex();
+ const auto *TII = MF.getSubtarget().getInstrInfo();
+ if (const auto *Formatter = TII->getMIRFormatter()) {
+ if (Formatter->parseCustomPseudoSourceValue(
+ Token.stringValue(), MF, PFS, PSV,
+ [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
+ return error(Loc, Msg);
+ }))
+ return true;
+ } else
+ return error("unable to parse target custom pseudo source value");
+ break;
+ }
default:
llvm_unreachable("The current token should be pseudo source value");
}
@@ -2759,7 +2886,7 @@ bool MIParser::parseMachinePointerInfo(MachinePointerInfo &Dest) {
if (Token.is(MIToken::kw_constant_pool) || Token.is(MIToken::kw_stack) ||
Token.is(MIToken::kw_got) || Token.is(MIToken::kw_jump_table) ||
Token.is(MIToken::FixedStackObject) || Token.is(MIToken::StackObject) ||
- Token.is(MIToken::kw_call_entry)) {
+ Token.is(MIToken::kw_call_entry) || Token.is(MIToken::kw_custom)) {
const PseudoSourceValue *PSV = nullptr;
if (parseMemoryPseudoSourceValue(PSV))
return true;
@@ -2956,6 +3083,22 @@ bool MIParser::parsePreOrPostInstrSymbol(MCSymbol *&Symbol) {
return false;
}
+bool MIParser::parseHeapAllocMarker(MDNode *&Node) {
+ assert(Token.is(MIToken::kw_heap_alloc_marker) &&
+ "Invalid token for a heap alloc marker!");
+ lex();
+ parseMDNode(Node);
+ if (!Node)
+ return error("expected a MDNode after 'heap-alloc-marker'");
+ if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
+ Token.is(MIToken::lbrace))
+ return false;
+ if (Token.isNot(MIToken::comma))
+ return error("expected ',' before the next machine operand");
+ lex();
+ return false;
+}
+
static void initSlots2BasicBlocks(
const Function &F,
DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
@@ -2994,37 +3137,6 @@ const BasicBlock *MIParser::getIRBlock(unsigned Slot, const Function &F) {
return getIRBlockFromSlot(Slot, CustomSlots2BasicBlocks);
}
-static void mapValueToSlot(const Value *V, ModuleSlotTracker &MST,
- DenseMap<unsigned, const Value *> &Slots2Values) {
- int Slot = MST.getLocalSlot(V);
- if (Slot == -1)
- return;
- Slots2Values.insert(std::make_pair(unsigned(Slot), V));
-}
-
-/// Creates the mapping from slot numbers to function's unnamed IR values.
-static void initSlots2Values(const Function &F,
- DenseMap<unsigned, const Value *> &Slots2Values) {
- ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
- MST.incorporateFunction(F);
- for (const auto &Arg : F.args())
- mapValueToSlot(&Arg, MST, Slots2Values);
- for (const auto &BB : F) {
- mapValueToSlot(&BB, MST, Slots2Values);
- for (const auto &I : BB)
- mapValueToSlot(&I, MST, Slots2Values);
- }
-}
-
-const Value *MIParser::getIRValue(unsigned Slot) {
- if (Slots2Values.empty())
- initSlots2Values(MF.getFunction(), Slots2Values);
- auto ValueInfo = Slots2Values.find(Slot);
- if (ValueInfo == Slots2Values.end())
- return nullptr;
- return ValueInfo->second;
-}
-
MCSymbol *MIParser::getOrCreateMCSymbol(StringRef Name) {
// FIXME: Currently we can't recognize temporary or local symbols and call all
// of the appropriate forms to create them. However, this handles basic cases
@@ -3087,3 +3199,15 @@ bool llvm::parseMDNode(PerFunctionMIParsingState &PFS,
MDNode *&Node, StringRef Src, SMDiagnostic &Error) {
return MIParser(PFS, Error, Src).parseStandaloneMDNode(Node);
}
+
+bool MIRFormatter::parseIRValue(StringRef Src, MachineFunction &MF,
+ PerFunctionMIParsingState &PFS, const Value *&V,
+ ErrorCallbackType ErrorCallback) {
+ MIToken Token;
+ Src = lexMIToken(Src, Token, [&](StringRef::iterator Loc, const Twine &Msg) {
+ ErrorCallback(Loc, Msg);
+ });
+ V = nullptr;
+
+ return ::parseIRValue(Token, PFS, V, ErrorCallback);
+}
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 55fac93d8991..10157c746b46 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -64,9 +64,12 @@ class MIRParserImpl {
/// parts.
bool NoMIRDocuments = false;
+ std::function<void(Function &)> ProcessIRFunction;
+
public:
- MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
- StringRef Filename, LLVMContext &Context);
+ MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
+ LLVMContext &Context,
+ std::function<void(Function &)> ProcessIRFunction);
void reportDiagnostic(const SMDiagnostic &Diag);
@@ -92,6 +95,9 @@ public:
/// Return null if an error occurred.
std::unique_ptr<Module> parseIRModule();
+ /// Create an empty function with the given name.
+ Function *createDummyFunction(StringRef Name, Module &M);
+
bool parseMachineFunctions(Module &M, MachineModuleInfo &MMI);
/// Parse the machine function in the current YAML document.
@@ -163,13 +169,13 @@ static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
}
MIRParserImpl::MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents,
- StringRef Filename, LLVMContext &Context)
+ StringRef Filename, LLVMContext &Context,
+ std::function<void(Function &)> Callback)
: SM(),
- In(SM.getMemoryBuffer(
- SM.AddNewSourceBuffer(std::move(Contents), SMLoc()))->getBuffer(),
- nullptr, handleYAMLDiag, this),
- Filename(Filename),
- Context(Context) {
+ In(SM.getMemoryBuffer(SM.AddNewSourceBuffer(std::move(Contents), SMLoc()))
+ ->getBuffer(),
+ nullptr, handleYAMLDiag, this),
+ Filename(Filename), Context(Context), ProcessIRFunction(Callback) {
In.setContext(&In);
}
@@ -256,14 +262,17 @@ bool MIRParserImpl::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
return false;
}
-/// Create an empty function with the given name.
-static Function *createDummyFunction(StringRef Name, Module &M) {
+Function *MIRParserImpl::createDummyFunction(StringRef Name, Module &M) {
auto &Context = M.getContext();
Function *F =
Function::Create(FunctionType::get(Type::getVoidTy(Context), false),
Function::ExternalLinkage, Name, M);
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
new UnreachableInst(Context, BB);
+
+ if (ProcessIRFunction)
+ ProcessIRFunction(*F);
+
return F;
}
@@ -925,21 +934,23 @@ bool MIRParser::parseMachineFunctions(Module &M, MachineModuleInfo &MMI) {
return Impl->parseMachineFunctions(M, MMI);
}
-std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(StringRef Filename,
- SMDiagnostic &Error,
- LLVMContext &Context) {
+std::unique_ptr<MIRParser> llvm::createMIRParserFromFile(
+ StringRef Filename, SMDiagnostic &Error, LLVMContext &Context,
+ std::function<void(Function &)> ProcessIRFunction) {
auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename);
if (std::error_code EC = FileOrErr.getError()) {
Error = SMDiagnostic(Filename, SourceMgr::DK_Error,
"Could not open input file: " + EC.message());
return nullptr;
}
- return createMIRParser(std::move(FileOrErr.get()), Context);
+ return createMIRParser(std::move(FileOrErr.get()), Context,
+ ProcessIRFunction);
}
std::unique_ptr<MIRParser>
llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
- LLVMContext &Context) {
+ LLVMContext &Context,
+ std::function<void(Function &)> ProcessIRFunction) {
auto Filename = Contents->getBufferIdentifier();
if (Context.shouldDiscardValueNames()) {
Context.diagnose(DiagnosticInfoMIRParser(
@@ -949,6 +960,6 @@ llvm::createMIRParser(std::unique_ptr<MemoryBuffer> Contents,
"Can't read MIR with a Context that discards named Values")));
return nullptr;
}
- return std::make_unique<MIRParser>(
- std::make_unique<MIRParserImpl>(std::move(Contents), Filename, Context));
+ return std::make_unique<MIRParser>(std::make_unique<MIRParserImpl>(
+ std::move(Contents), Filename, Context, ProcessIRFunction));
}