summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Target/TargetInstrInfo.h17
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.cpp1
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.h1
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.cpp68
-rw-r--r--llvm/lib/CodeGen/MIRPrinter.cpp34
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.cpp35
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.h6
-rw-r--r--llvm/test/CodeGen/MIR/X86/expected-target-flag-name.mir26
-rw-r--r--llvm/test/CodeGen/MIR/X86/global-value-operands.mir20
-rw-r--r--llvm/test/CodeGen/MIR/X86/invalid-target-flag-name.mir26
-rw-r--r--llvm/test/CodeGen/MIR/X86/register-operands-target-flag-error.mir26
11 files changed, 247 insertions, 13 deletions
diff --git a/llvm/include/llvm/Target/TargetInstrInfo.h b/llvm/include/llvm/Target/TargetInstrInfo.h
index 07b57713062..0b45507893a 100644
--- a/llvm/include/llvm/Target/TargetInstrInfo.h
+++ b/llvm/include/llvm/Target/TargetInstrInfo.h
@@ -1272,6 +1272,23 @@ public:
return None;
}
+ /// Decompose the machine operand's target flags into two values - the direct
+ /// target flag value and any of bit flags that are applied.
+ virtual std::pair<unsigned, unsigned>
+ decomposeMachineOperandsTargetFlags(unsigned /*TF*/) const {
+ return std::make_pair(0u, 0u);
+ }
+
+ /// Return an array that contains the direct target flag values and their
+ /// names.
+ ///
+ /// MIR Serialization is able to serialize only the target flags that are
+ /// defined by this method.
+ virtual ArrayRef<std::pair<unsigned, const char *>>
+ getSerializableDirectMachineOperandTargetFlags() const {
+ return None;
+ }
+
private:
unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode;
};
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
index fece542d60e..892a15f9273 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -173,6 +173,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
.Case("x86_fp80", MIToken::kw_x86_fp80)
.Case("fp128", MIToken::kw_fp128)
.Case("ppc_fp128", MIToken::kw_ppc_fp128)
+ .Case("target-flags", MIToken::kw_target_flags)
.Case("volatile", MIToken::kw_volatile)
.Default(MIToken::Identifier);
}
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h
index 064f68e2d5d..407a85a32a1 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.h
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -65,6 +65,7 @@ struct MIToken {
kw_x86_fp80,
kw_fp128,
kw_ppc_fp128,
+ kw_target_flags,
kw_volatile,
// Identifier tokens
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 1a47c5865bb..1596889b065 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -70,6 +70,8 @@ class MIParser {
DenseMap<unsigned, const BasicBlock *> Slots2BasicBlocks;
/// Maps from target index names to target indices.
StringMap<int> Names2TargetIndices;
+ /// Maps from direct target flag names to the direct target flag values.
+ StringMap<unsigned> Names2DirectTargetFlags;
public:
MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error,
@@ -120,6 +122,7 @@ public:
bool parseBlockAddressOperand(MachineOperand &Dest);
bool parseTargetIndexOperand(MachineOperand &Dest);
bool parseMachineOperand(MachineOperand &Dest);
+ bool parseMachineOperandAndTargetFlags(MachineOperand &Dest);
bool parseOperandsOffset(MachineOperand &Op);
bool parseIRValue(Value *&V);
bool parseMemoryOperandFlag(unsigned &Flags);
@@ -181,6 +184,14 @@ private:
///
/// Return true if the name isn't a name of a target index.
bool getTargetIndex(StringRef Name, int &Index);
+
+ void initNames2DirectTargetFlags();
+
+ /// Try to convert a name of a direct target flag to the corresponding
+ /// target flag.
+ ///
+ /// Return true if the name isn't a name of a direct flag.
+ bool getDirectTargetFlag(StringRef Name, unsigned &Flag);
};
} // end anonymous namespace
@@ -258,7 +269,7 @@ bool MIParser::parse(MachineInstr *&MI) {
while (Token.isNot(MIToken::Eof) && Token.isNot(MIToken::kw_debug_location) &&
Token.isNot(MIToken::coloncolon)) {
auto Loc = Token.location();
- if (parseMachineOperand(MO))
+ if (parseMachineOperandAndTargetFlags(MO))
return true;
Operands.push_back(MachineOperandWithLocation(MO, Loc, Token.location()));
if (Token.is(MIToken::Eof) || Token.is(MIToken::coloncolon))
@@ -696,7 +707,6 @@ bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) {
return true;
lex();
Dest = MachineOperand::CreateGA(GV, /*Offset=*/0);
- // TODO: Parse the target flags.
if (parseOperandsOffset(Dest))
return true;
return false;
@@ -711,7 +721,6 @@ bool MIParser::parseConstantPoolIndexOperand(MachineOperand &Dest) {
if (ConstantInfo == PFS.ConstantPoolSlots.end())
return error("use of undefined constant '%const." + Twine(ID) + "'");
lex();
- // TODO: Parse the target flags.
Dest = MachineOperand::CreateCPI(ID, /*Offset=*/0);
if (parseOperandsOffset(Dest))
return true;
@@ -727,7 +736,6 @@ bool MIParser::parseJumpTableIndexOperand(MachineOperand &Dest) {
if (JumpTableEntryInfo == PFS.JumpTableSlots.end())
return error("use of undefined jump table '%jump-table." + Twine(ID) + "'");
lex();
- // TODO: Parse target flags.
Dest = MachineOperand::CreateJTI(JumpTableEntryInfo->second);
return false;
}
@@ -736,7 +744,6 @@ bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) {
assert(Token.is(MIToken::ExternalSymbol));
const char *Symbol = MF.createExternalSymbolName(Token.stringValue());
lex();
- // TODO: Parse the target flags.
Dest = MachineOperand::CreateES(Symbol);
if (parseOperandsOffset(Dest))
return true;
@@ -889,7 +896,6 @@ bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) {
lex();
if (expectAndConsume(MIToken::rparen))
return true;
- // TODO: parse the target flags.
Dest = MachineOperand::CreateBA(BlockAddress::get(F, BB), /*Offset=*/0);
if (parseOperandsOffset(Dest))
return true;
@@ -909,7 +915,6 @@ bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) {
lex();
if (expectAndConsume(MIToken::rparen))
return true;
- // TODO: Parse the target flags.
Dest = MachineOperand::CreateTargetIndex(unsigned(Index), /*Offset=*/0);
if (parseOperandsOffset(Dest))
return true;
@@ -982,6 +987,35 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) {
return false;
}
+bool MIParser::parseMachineOperandAndTargetFlags(MachineOperand &Dest) {
+ unsigned TF = 0;
+ bool HasTargetFlags = false;
+ if (Token.is(MIToken::kw_target_flags)) {
+ HasTargetFlags = true;
+ lex();
+ if (expectAndConsume(MIToken::lparen))
+ return true;
+ if (Token.isNot(MIToken::Identifier))
+ return error("expected the name of the target flag");
+ if (getDirectTargetFlag(Token.stringValue(), TF))
+ return error("use of undefined target flag '" + Token.stringValue() +
+ "'");
+ lex();
+ // TODO: Parse target's bit target flags.
+ if (expectAndConsume(MIToken::rparen))
+ return true;
+ }
+ auto Loc = Token.location();
+ if (parseMachineOperand(Dest))
+ return true;
+ if (!HasTargetFlags)
+ return false;
+ if (Dest.isReg())
+ return error(Loc, "register operands can't have target flags");
+ Dest.setTargetFlags(TF);
+ return false;
+}
+
bool MIParser::parseOperandsOffset(MachineOperand &Op) {
if (Token.isNot(MIToken::plus) && Token.isNot(MIToken::minus))
return false;
@@ -1209,6 +1243,26 @@ bool MIParser::getTargetIndex(StringRef Name, int &Index) {
return false;
}
+void MIParser::initNames2DirectTargetFlags() {
+ if (!Names2DirectTargetFlags.empty())
+ return;
+ const auto *TII = MF.getSubtarget().getInstrInfo();
+ assert(TII && "Expected target instruction info");
+ auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
+ for (const auto &I : Flags)
+ Names2DirectTargetFlags.insert(
+ std::make_pair(StringRef(I.second), I.first));
+}
+
+bool MIParser::getDirectTargetFlag(StringRef Name, unsigned &Flag) {
+ initNames2DirectTargetFlags();
+ auto FlagInfo = Names2DirectTargetFlags.find(Name);
+ if (FlagInfo == Names2DirectTargetFlags.end())
+ return true;
+ Flag = FlagInfo->second;
+ return false;
+}
+
bool llvm::parseMachineInstr(MachineInstr *&MI, SourceMgr &SM,
MachineFunction &MF, StringRef Src,
const PerFunctionMIParsingState &PFS,
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 9af64823d04..a166dd58fe4 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -118,6 +118,7 @@ public:
void printIRValueReference(const Value &V);
void printStackObjectReference(int FrameIndex);
void printOffset(int64_t Offset);
+ void printTargetFlags(const MachineOperand &Op);
void print(const MachineOperand &Op, const TargetRegisterInfo *TRI);
void print(const MachineMemOperand &Op);
@@ -516,6 +517,32 @@ void MIPrinter::printOffset(int64_t Offset) {
OS << " + " << Offset;
}
+static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
+ auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
+ for (const auto &I : Flags) {
+ if (I.first == TF) {
+ return I.second;
+ }
+ }
+ return nullptr;
+}
+
+void MIPrinter::printTargetFlags(const MachineOperand &Op) {
+ if (!Op.getTargetFlags())
+ return;
+ const auto *TII =
+ Op.getParent()->getParent()->getParent()->getSubtarget().getInstrInfo();
+ assert(TII && "expected instruction info");
+ auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags());
+ OS << "target-flags(";
+ if (const auto *Name = getTargetFlagName(TII, Flags.first))
+ OS << Name;
+ else
+ OS << "<unknown target flag>";
+ // TODO: Print the target's bit flags.
+ OS << ") ";
+}
+
static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
const auto *TII = MF.getSubtarget().getInstrInfo();
assert(TII && "expected instruction info");
@@ -529,6 +556,7 @@ static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
}
void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
+ printTargetFlags(Op);
switch (Op.getType()) {
case MachineOperand::MO_Register:
// TODO: Print the other register flags.
@@ -567,7 +595,6 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
case MachineOperand::MO_ConstantPoolIndex:
OS << "%const." << Op.getIndex();
printOffset(Op.getOffset());
- // TODO: Print the target flags.
break;
case MachineOperand::MO_TargetIndex: {
OS << "target-index(";
@@ -578,23 +605,19 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
OS << "<unknown>";
OS << ')';
printOffset(Op.getOffset());
- // TODO: Print the target flags.
break;
}
case MachineOperand::MO_JumpTableIndex:
OS << "%jump-table." << Op.getIndex();
- // TODO: Print target flags.
break;
case MachineOperand::MO_ExternalSymbol:
OS << '$';
printLLVMNameWithoutPrefix(OS, Op.getSymbolName());
printOffset(Op.getOffset());
- // TODO: Print the target flags.
break;
case MachineOperand::MO_GlobalAddress:
Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
printOffset(Op.getOffset());
- // TODO: Print the target flags.
break;
case MachineOperand::MO_BlockAddress:
OS << "blockaddress(";
@@ -604,7 +627,6 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
printIRBlockReference(*Op.getBlockAddress()->getBasicBlock());
OS << ')';
printOffset(Op.getOffset());
- // TODO: Print the target flags.
break;
case MachineOperand::MO_RegisterMask: {
auto RegMaskInfo = RegisterMaskIds.find(Op.getRegMask());
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index 810fdb77a0d..01d59f9a8b4 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -6581,6 +6581,41 @@ void X86InstrInfo::genAlternativeCodeSequence(
return;
}
+std::pair<unsigned, unsigned>
+X86InstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
+ return std::make_pair(TF, 0u);
+}
+
+ArrayRef<std::pair<unsigned, const char *>>
+X86InstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
+ using namespace X86II;
+ static std::pair<unsigned, const char *> TargetFlags[] = {
+ {MO_GOT_ABSOLUTE_ADDRESS, "x86-got-absolute-address"},
+ {MO_PIC_BASE_OFFSET, "x86-pic-base-offset"},
+ {MO_GOT, "x86-got"},
+ {MO_GOTOFF, "x86-gotoff"},
+ {MO_GOTPCREL, "x86-gotpcrel"},
+ {MO_PLT, "x86-plt"},
+ {MO_TLSGD, "x86-tlsgd"},
+ {MO_TLSLD, "x86-tlsld"},
+ {MO_TLSLDM, "x86-tlsldm"},
+ {MO_GOTTPOFF, "x86-gottpoff"},
+ {MO_INDNTPOFF, "x86-indntpoff"},
+ {MO_TPOFF, "x86-tpoff"},
+ {MO_DTPOFF, "x86-dtpoff"},
+ {MO_NTPOFF, "x86-ntpoff"},
+ {MO_GOTNTPOFF, "x86-gotntpoff"},
+ {MO_DLLIMPORT, "x86-dllimport"},
+ {MO_DARWIN_STUB, "x86-darwin-stub"},
+ {MO_DARWIN_NONLAZY, "x86-darwin-nonlazy"},
+ {MO_DARWIN_NONLAZY_PIC_BASE, "x86-darwin-nonlazy-pic-base"},
+ {MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE, "x86-darwin-hidden-nonlazy-pic-base"},
+ {MO_TLVP, "x86-tlvp"},
+ {MO_TLVP_PIC_BASE, "x86-tlvp-pic-base"},
+ {MO_SECREL, "x86-secrel"}};
+ return makeArrayRef(TargetFlags);
+}
+
namespace {
/// Create Global Base Reg pass. This initializes the PIC
/// global base register for x86-32.
diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h
index 0ef4b088eac..71a48866df4 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.h
+++ b/llvm/lib/Target/X86/X86InstrInfo.h
@@ -495,6 +495,12 @@ public:
unsigned &FoldAsLoadDefReg,
MachineInstr *&DefMI) const override;
+ std::pair<unsigned, unsigned>
+ decomposeMachineOperandsTargetFlags(unsigned TF) const override;
+
+ ArrayRef<std::pair<unsigned, const char *>>
+ getSerializableDirectMachineOperandTargetFlags() const override;
+
private:
MachineInstr * convertToThreeAddressWithLEA(unsigned MIOpc,
MachineFunction::iterator &MFI,
diff --git a/llvm/test/CodeGen/MIR/X86/expected-target-flag-name.mir b/llvm/test/CodeGen/MIR/X86/expected-target-flag-name.mir
new file mode 100644
index 00000000000..a885a566b67
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/X86/expected-target-flag-name.mir
@@ -0,0 +1,26 @@
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+
+--- |
+
+ @G = external global i32
+
+ define i32 @inc() {
+ entry:
+ %a = load i32, i32* @G
+ %b = add i32 %a, 1
+ ret i32 %b
+ }
+
+...
+---
+name: inc
+body:
+ - id: 0
+ name: entry
+ instructions:
+# CHECK: [[@LINE+1]]:51: expected the name of the target flag
+ - '%rax = MOV64rm %rip, 1, _, target-flags( ) @G, _'
+ - '%eax = MOV32rm killed %rax, 1, _, 0, _'
+ - '%eax = INC32r killed %eax, implicit-def dead %eflags'
+ - 'RETQ %eax'
+...
diff --git a/llvm/test/CodeGen/MIR/X86/global-value-operands.mir b/llvm/test/CodeGen/MIR/X86/global-value-operands.mir
index 251d1ff3617..f29ed358a71 100644
--- a/llvm/test/CodeGen/MIR/X86/global-value-operands.mir
+++ b/llvm/test/CodeGen/MIR/X86/global-value-operands.mir
@@ -51,6 +51,13 @@
ret i32 %b
}
+ define i32 @tf() {
+ entry:
+ %a = load i32, i32* @G
+ %b = add i32 %a, 1
+ ret i32 %b
+ }
+
...
---
# CHECK: name: inc
@@ -130,3 +137,16 @@ body:
- 'MOV32mr killed %rcx, 1, _, 0, _, %eax'
- 'RETQ %eax'
...
+---
+# CHECK: name: tf
+name: tf
+body:
+ - id: 0
+ name: entry
+ instructions:
+# CHECK: %rax = MOV64rm %rip, 1, _, target-flags(x86-gotpcrel) @G, _
+ - '%rax = MOV64rm %rip, 1, _, target-flags(x86-gotpcrel) @G, _'
+ - '%eax = MOV32rm %rax, 1, _, 0, _'
+ - '%eax = INC32r %eax, implicit-def %eflags'
+ - 'RETQ %eax'
+...
diff --git a/llvm/test/CodeGen/MIR/X86/invalid-target-flag-name.mir b/llvm/test/CodeGen/MIR/X86/invalid-target-flag-name.mir
new file mode 100644
index 00000000000..1e1fc7b302d
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/X86/invalid-target-flag-name.mir
@@ -0,0 +1,26 @@
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+
+--- |
+
+ @G = external global i32
+
+ define i32 @inc() {
+ entry:
+ %a = load i32, i32* @G
+ %b = add i32 %a, 1
+ ret i32 %b
+ }
+
+...
+---
+name: inc
+body:
+ - id: 0
+ name: entry
+ instructions:
+# CHECK: [[@LINE+1]]:50: use of undefined target flag 'x86-test'
+ - '%rax = MOV64rm %rip, 1, _, target-flags(x86-test) @G, _'
+ - '%eax = MOV32rm killed %rax, 1, _, 0, _'
+ - '%eax = INC32r killed %eax, implicit-def dead %eflags'
+ - 'RETQ %eax'
+...
diff --git a/llvm/test/CodeGen/MIR/X86/register-operands-target-flag-error.mir b/llvm/test/CodeGen/MIR/X86/register-operands-target-flag-error.mir
new file mode 100644
index 00000000000..219a0d32ae9
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/X86/register-operands-target-flag-error.mir
@@ -0,0 +1,26 @@
+# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s
+
+--- |
+
+ @G = external global i32
+
+ define i32 @inc() {
+ entry:
+ %a = load i32, i32* @G
+ %b = add i32 %a, 1
+ ret i32 %b
+ }
+
+...
+---
+name: inc
+body:
+ - id: 0
+ name: entry
+ instructions:
+# CHECK: [[@LINE+1]]:47: register operands can't have target flags
+ - '%rax = MOV64rm target-flags(x86-got) %rip, 1, _, @G, _'
+ - '%eax = MOV32rm killed %rax, 1, _, 0, _'
+ - '%eax = INC32r killed %eax, implicit-def dead %eflags'
+ - 'RETQ %eax'
+...
OpenPOWER on IntegriCloud