summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp8
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.cpp51
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.h3
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.cpp67
-rw-r--r--llvm/lib/CodeGen/MIRPrinter.cpp18
-rw-r--r--llvm/lib/CodeGen/MachineInstr.cpp92
6 files changed, 210 insertions, 29 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 0271e21e59c..3fe5a0bc46e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1066,6 +1066,10 @@ void AsmPrinter::EmitFunctionBody() {
++NumInstsInFunction;
}
+ // If there is a pre-instruction symbol, emit a label for it here.
+ if (MCSymbol *S = MI.getPreInstrSymbol())
+ OutStreamer->EmitLabel(S);
+
if (ShouldPrintDebugScopes) {
for (const HandlerInfo &HI : Handlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription,
@@ -1117,6 +1121,10 @@ void AsmPrinter::EmitFunctionBody() {
break;
}
+ // If there is a post-instruction symbol, emit a label for it here.
+ if (MCSymbol *S = MI.getPostInstrSymbol())
+ OutStreamer->EmitLabel(S);
+
if (ShouldPrintDebugScopes) {
for (const HandlerInfo &HI : Handlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerDescription,
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
index da05c9a2278..400e0981a16 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -245,6 +245,8 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("successors", MIToken::kw_successors)
.Case("floatpred", MIToken::kw_floatpred)
.Case("intpred", MIToken::kw_intpred)
+ .Case("pre-instr-symbol", MIToken::kw_pre_instr_symbol)
+ .Case("post-instr-symbol", MIToken::kw_post_instr_symbol)
.Default(MIToken::Identifier);
}
@@ -460,6 +462,53 @@ static Cursor maybeLexExternalSymbol(Cursor C, MIToken &Token,
ErrorCallback);
}
+static Cursor maybeLexMCSymbol(Cursor C, MIToken &Token,
+ ErrorCallbackType ErrorCallback) {
+ const StringRef Rule = "<mcsymbol ";
+ if (!C.remaining().startswith(Rule))
+ return None;
+ auto Start = C;
+ C.advance(Rule.size());
+
+ // Try a simple unquoted name.
+ if (C.peek() != '"') {
+ while (isIdentifierChar(C.peek()))
+ C.advance();
+ StringRef String = Start.upto(C).drop_front(Rule.size());
+ if (C.peek() != '>') {
+ ErrorCallback(C.location(),
+ "expected the '<mcsymbol ...' to be closed by a '>'");
+ Token.reset(MIToken::Error, Start.remaining());
+ return Start;
+ }
+ C.advance();
+
+ Token.reset(MIToken::MCSymbol, Start.upto(C)).setStringValue(String);
+ return C;
+ }
+
+ // Otherwise lex out a quoted name.
+ Cursor R = lexStringConstant(C, ErrorCallback);
+ if (!R) {
+ ErrorCallback(C.location(),
+ "unable to parse quoted string from opening quote");
+ Token.reset(MIToken::Error, Start.remaining());
+ return Start;
+ }
+ StringRef String = Start.upto(R).drop_front(Rule.size());
+ if (R.peek() != '>') {
+ ErrorCallback(R.location(),
+ "expected the '<mcsymbol ...' to be closed by a '>'");
+ Token.reset(MIToken::Error, Start.remaining());
+ return Start;
+ }
+ R.advance();
+
+ Token.reset(MIToken::MCSymbol, Start.upto(R))
+ .setOwnedStringValue(unescapeQuotedString(String));
+ return R;
+}
+
static bool isValidHexFloatingPointPrefix(char C) {
return C == 'H' || C == 'K' || C == 'L' || C == 'M';
}
@@ -657,6 +706,8 @@ StringRef llvm::lexMIToken(StringRef Source, MIToken &Token,
return R.remaining();
if (Cursor R = maybeLexExternalSymbol(C, Token, ErrorCallback))
return R.remaining();
+ if (Cursor R = maybeLexMCSymbol(C, Token, ErrorCallback))
+ return R.remaining();
if (Cursor R = maybeLexHexadecimalLiteral(C, Token))
return R.remaining();
if (Cursor R = maybeLexNumericalLiteral(C, Token))
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h
index e21c71532f7..94b460e9ac2 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.h
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -113,6 +113,8 @@ struct MIToken {
kw_successors,
kw_floatpred,
kw_intpred,
+ kw_pre_instr_symbol,
+ kw_post_instr_symbol,
// Named metadata keywords
md_tbaa,
@@ -132,6 +134,7 @@ struct MIToken {
NamedGlobalValue,
GlobalValue,
ExternalSymbol,
+ MCSymbol,
// Other tokens
IntegerLiteral,
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 86d4a380ac7..956f6eceb82 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -54,6 +54,7 @@
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/MC/LaneBitmask.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCRegisterInfo.h"
@@ -221,6 +222,7 @@ public:
bool parseSubRegisterIndexOperand(MachineOperand &Dest);
bool parseJumpTableIndexOperand(MachineOperand &Dest);
bool parseExternalSymbolOperand(MachineOperand &Dest);
+ bool parseMCSymbolOperand(MachineOperand &Dest);
bool parseMDNode(MDNode *&Node);
bool parseDIExpression(MDNode *&Expr);
bool parseMetadataOperand(MachineOperand &Dest);
@@ -250,6 +252,7 @@ public:
bool parseOptionalScope(LLVMContext &Context, SyncScope::ID &SSID);
bool parseOptionalAtomicOrdering(AtomicOrdering &Order);
bool parseMachineMemoryOperand(MachineMemOperand *&Dest);
+ bool parsePreOrPostInstrSymbol(MCSymbol *&Symbol);
private:
/// Convert the integer literal in the current token into an unsigned integer.
@@ -346,6 +349,9 @@ private:
/// Return true if the name isn't a name of a target MMO flag.
bool getMMOTargetFlag(StringRef Name, MachineMemOperand::Flags &Flag);
+ /// Get or create an MCSymbol for a given name.
+ MCSymbol *getOrCreateMCSymbol(StringRef Name);
+
/// parseStringConstant
/// ::= StringConstant
bool parseStringConstant(std::string &Result);
@@ -737,7 +743,9 @@ bool MIParser::parse(MachineInstr *&MI) {
return true;
// Parse the remaining machine operands.
- while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_debug_location) &&
+ while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_pre_instr_symbol) &&
+ Token.isNot(MIToken::kw_post_instr_symbol) &&
+ Token.isNot(MIToken::kw_debug_location) &&
Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) {
auto Loc = Token.location();
Optional<unsigned> TiedDefIdx;
@@ -753,6 +761,15 @@ bool MIParser::parse(MachineInstr *&MI) {
lex();
}
+ MCSymbol *PreInstrSymbol = nullptr;
+ if (Token.is(MIToken::kw_pre_instr_symbol))
+ if (parsePreOrPostInstrSymbol(PreInstrSymbol))
+ return true;
+ MCSymbol *PostInstrSymbol = nullptr;
+ if (Token.is(MIToken::kw_post_instr_symbol))
+ if (parsePreOrPostInstrSymbol(PostInstrSymbol))
+ return true;
+
DebugLoc DebugLocation;
if (Token.is(MIToken::kw_debug_location)) {
lex();
@@ -795,9 +812,12 @@ bool MIParser::parse(MachineInstr *&MI) {
MI->addOperand(MF, Operand.Operand);
if (assignRegisterTies(*MI, Operands))
return true;
- if (MemOperands.empty())
- return false;
- MI->setMemRefs(MF, MemOperands);
+ if (PreInstrSymbol)
+ MI->setPreInstrSymbol(MF, PreInstrSymbol);
+ if (PostInstrSymbol)
+ MI->setPostInstrSymbol(MF, PostInstrSymbol);
+ if (!MemOperands.empty())
+ MI->setMemRefs(MF, MemOperands);
return false;
}
@@ -1570,6 +1590,16 @@ bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) {
return false;
}
+bool MIParser::parseMCSymbolOperand(MachineOperand &Dest) {
+ assert(Token.is(MIToken::MCSymbol));
+ MCSymbol *Symbol = getOrCreateMCSymbol(Token.stringValue());
+ lex();
+ Dest = MachineOperand::CreateMCSymbol(Symbol);
+ if (parseOperandsOffset(Dest))
+ return true;
+ return false;
+}
+
bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) {
assert(Token.is(MIToken::SubRegisterIndex));
StringRef Name = Token.stringValue();
@@ -2047,6 +2077,8 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest,
return parseJumpTableIndexOperand(Dest);
case MIToken::ExternalSymbol:
return parseExternalSymbolOperand(Dest);
+ case MIToken::MCSymbol:
+ return parseMCSymbolOperand(Dest);
case MIToken::SubRegisterIndex:
return parseSubRegisterIndexOperand(Dest);
case MIToken::md_diexpr:
@@ -2526,6 +2558,24 @@ bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) {
return false;
}
+bool MIParser::parsePreOrPostInstrSymbol(MCSymbol *&Symbol) {
+ assert((Token.is(MIToken::kw_pre_instr_symbol) ||
+ Token.is(MIToken::kw_post_instr_symbol)) &&
+ "Invalid token for a pre- post-instruction symbol!");
+ lex();
+ if (Token.isNot(MIToken::MCSymbol))
+ return error("expected a symbol after 'pre-instr-symbol'");
+ Symbol = getOrCreateMCSymbol(Token.stringValue());
+ lex();
+ 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;
+}
+
void MIParser::initNames2InstrOpCodes() {
if (!Names2InstrOpCodes.empty())
return;
@@ -2756,6 +2806,15 @@ bool MIParser::getMMOTargetFlag(StringRef Name,
return false;
}
+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
+ // well as most of the special aspects are recognized by a prefix on their
+ // name, and the input names should already be unique. For test cases, keeping
+ // the symbol name out of the symbol table isn't terribly important.
+ return MF.getContext().getOrCreateSymbol(Name);
+}
+
bool MIParser::parseStringConstant(std::string &Result) {
if (Token.isNot(MIToken::StringConstant))
return error("expected string constant");
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index bf8cd1489ec..67c54631fa6 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -50,6 +50,7 @@
#include "llvm/IR/ModuleSlotTracker.h"
#include "llvm/IR/Value.h"
#include "llvm/MC/LaneBitmask.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/AtomicOrdering.h"
@@ -708,6 +709,23 @@ void MIPrinter::print(const MachineInstr &MI) {
NeedComma = true;
}
+ // Print any optional symbols attached to this instruction as-if they were
+ // operands.
+ if (MCSymbol *PreInstrSymbol = MI.getPreInstrSymbol()) {
+ if (NeedComma)
+ OS << ',';
+ OS << " pre-instr-symbol ";
+ MachineOperand::printSymbol(OS, *PreInstrSymbol);
+ NeedComma = true;
+ }
+ if (MCSymbol *PostInstrSymbol = MI.getPostInstrSymbol()) {
+ if (NeedComma)
+ OS << ',';
+ OS << " post-instr-symbol ";
+ MachineOperand::printSymbol(OS, *PostInstrSymbol);
+ NeedComma = true;
+ }
+
if (const DebugLoc &DL = MI.getDebugLoc()) {
if (NeedComma)
OS << ',';
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index fb1d392e01b..9503537dd67 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -447,45 +447,68 @@ void MachineInstr::cloneMergedMemRefs(MachineFunction &MF,
setMemRefs(MF, MergedMMOs);
}
-MCSymbol *MachineInstr::getOrCreatePreInstrTempSymbol(MCContext &MCCtx) {
- MCSymbol *S = getPreInstrSymbol();
- if (S)
- return S;
+void MachineInstr::setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
+ MCSymbol *OldSymbol = getPreInstrSymbol();
+ if (OldSymbol == Symbol)
+ return;
+ if (OldSymbol && !Symbol) {
+ // We're removing a symbol rather than adding one. Try to clean up any
+ // extra info carried around.
+ if (Info.is<EIIK_PreInstrSymbol>()) {
+ Info.clear();
+ return;
+ }
- // Create a new temp symbol.
- S = MCCtx.createTempSymbol();
+ if (memoperands_empty()) {
+ assert(getPostInstrSymbol() &&
+ "Should never have only a single symbol allocated out-of-line!");
+ Info.set<EIIK_PostInstrSymbol>(getPostInstrSymbol());
+ return;
+ }
- if (!Info) {
+ // Otherwise fallback on the generic update.
+ } else if (!Info || Info.is<EIIK_PreInstrSymbol>()) {
// If we don't have any other extra info, we can store this inline.
- Info.set<EIIK_PreInstrSymbol>(S);
- return S;
+ Info.set<EIIK_PreInstrSymbol>(Symbol);
+ return;
}
- // Otherwise, allocate a fully set of extra info.
+ // Otherwise, allocate a full new set of extra info.
+ // FIXME: Maybe we should make the symbols in the extra info mutable?
Info.set<EIIK_OutOfLine>(
- getMF()->createMIExtraInfo(memoperands(), S, getPostInstrSymbol()));
-
- return S;
+ MF.createMIExtraInfo(memoperands(), Symbol, getPostInstrSymbol()));
}
-MCSymbol *MachineInstr::getOrCreatePostInstrTempSymbol(MCContext &MCCtx) {
- MCSymbol *S = getPostInstrSymbol();
- if (S)
- return S;
+void MachineInstr::setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
+ MCSymbol *OldSymbol = getPostInstrSymbol();
+ if (OldSymbol == Symbol)
+ return;
+ if (OldSymbol && !Symbol) {
+ // We're removing a symbol rather than adding one. Try to clean up any
+ // extra info carried around.
+ if (Info.is<EIIK_PostInstrSymbol>()) {
+ Info.clear();
+ return;
+ }
- // Create a new temp symbol.
- S = MCCtx.createTempSymbol();
+ if (memoperands_empty()) {
+ assert(getPreInstrSymbol() &&
+ "Should never have only a single symbol allocated out-of-line!");
+ Info.set<EIIK_PreInstrSymbol>(getPreInstrSymbol());
+ return;
+ }
- if (!Info) {
+ // Otherwise fallback on the generic update.
+ } else if (!Info || Info.is<EIIK_PostInstrSymbol>()) {
// If we don't have any other extra info, we can store this inline.
- Info.set<EIIK_PostInstrSymbol>(S);
- return S;
+ Info.set<EIIK_PostInstrSymbol>(Symbol);
+ return;
}
- // Otherwise, allocate a fully set of extra info.
+ // Otherwise, allocate a full new set of extra info.
+ // FIXME: Maybe we should make the symbols in the extra info mutable?
Info.set<EIIK_OutOfLine>(
- getMF()->createMIExtraInfo(memoperands(), getPreInstrSymbol(), S));
- return S;
+ MF.createMIExtraInfo(memoperands(), getPreInstrSymbol(), Symbol));
}
uint16_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const {
@@ -1592,6 +1615,25 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
}
}
+ // Print any optional symbols attached to this instruction as-if they were
+ // operands.
+ if (MCSymbol *PreInstrSymbol = getPreInstrSymbol()) {
+ if (!FirstOp) {
+ FirstOp = false;
+ OS << ',';
+ }
+ OS << " pre-instr-symbol ";
+ MachineOperand::printSymbol(OS, *PreInstrSymbol);
+ }
+ if (MCSymbol *PostInstrSymbol = getPostInstrSymbol()) {
+ if (!FirstOp) {
+ FirstOp = false;
+ OS << ',';
+ }
+ OS << " post-instr-symbol ";
+ MachineOperand::printSymbol(OS, *PostInstrSymbol);
+ }
+
if (!SkipDebugLoc) {
if (const DebugLoc &DL = getDebugLoc()) {
if (!FirstOp)
OpenPOWER on IntegriCloud