summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/CMakeLists.txt1
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp4
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp14
-rw-r--r--llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp46
-rw-r--r--llvm/lib/CodeGen/LowLevelType.cpp46
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.cpp10
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.h1
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.cpp77
-rw-r--r--llvm/lib/CodeGen/MIRPrinter.cpp4
-rw-r--r--llvm/lib/CodeGen/MachineInstr.cpp18
10 files changed, 129 insertions, 92 deletions
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index d103a68c60d..cdb3eb7efb2 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -48,6 +48,7 @@ add_llvm_library(LLVMCodeGen
LiveVariables.cpp
LLVMTargetMachine.cpp
LocalStackSlotAllocation.cpp
+ LowLevelType.cpp
LowerEmuTLS.cpp
MachineBasicBlock.cpp
MachineBlockFrequencyInfo.cpp
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index b8a960cfac7..32046771066 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -69,7 +69,7 @@ bool IRTranslator::translateBinaryOp(unsigned Opcode, const Instruction &Inst) {
unsigned Op0 = getOrCreateVReg(*Inst.getOperand(0));
unsigned Op1 = getOrCreateVReg(*Inst.getOperand(1));
unsigned Res = getOrCreateVReg(Inst);
- MIRBuilder.buildInstr(Opcode, Inst.getType(), Res, Op0, Op1);
+ MIRBuilder.buildInstr(Opcode, LLT{*Inst.getType()}, Res, Op0, Op1);
return true;
}
@@ -88,7 +88,7 @@ bool IRTranslator::translateBr(const Instruction &Inst) {
if (BrInst.isUnconditional()) {
const BasicBlock &BrTgt = *cast<BasicBlock>(BrInst.getOperand(0));
MachineBasicBlock &TgtBB = getOrCreateBB(BrTgt);
- MIRBuilder.buildInstr(TargetOpcode::G_BR, BrTgt.getType(), TgtBB);
+ MIRBuilder.buildInstr(TargetOpcode::G_BR, LLT{*BrTgt.getType()}, TgtBB);
} else {
assert(0 && "Not yet implemented");
}
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 2f19bcf1e68..382652fe5bc 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -56,9 +56,9 @@ MachineBasicBlock::iterator MachineIRBuilder::getInsertPt() {
//------------------------------------------------------------------------------
// Build instruction variants.
//------------------------------------------------------------------------------
-MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, Type *Ty) {
+MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty) {
MachineInstr *NewMI = BuildMI(getMF(), DL, getTII().get(Opcode));
- if (Ty) {
+ if (Ty.isValid()) {
assert(isPreISelGenericOpcode(Opcode) &&
"Only generic instruction can have a type");
NewMI->setType(Ty);
@@ -71,10 +71,10 @@ MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, Type *Ty) {
MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, unsigned Res,
unsigned Op0, unsigned Op1) {
- return buildInstr(Opcode, nullptr, Res, Op0, Op1);
+ return buildInstr(Opcode, LLT{}, Res, Op0, Op1);
}
-MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, Type *Ty,
+MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty,
unsigned Res, unsigned Op0,
unsigned Op1) {
MachineInstr *NewMI = buildInstr(Opcode, Ty);
@@ -87,16 +87,16 @@ MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, Type *Ty,
MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, unsigned Res,
unsigned Op0) {
- MachineInstr *NewMI = buildInstr(Opcode, nullptr);
+ MachineInstr *NewMI = buildInstr(Opcode, LLT{});
MachineInstrBuilder(getMF(), NewMI).addReg(Res, RegState::Define).addReg(Op0);
return NewMI;
}
MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode) {
- return buildInstr(Opcode, nullptr);
+ return buildInstr(Opcode, LLT{});
}
-MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, Type *Ty,
+MachineInstr *MachineIRBuilder::buildInstr(unsigned Opcode, LLT Ty,
MachineBasicBlock &BB) {
MachineInstr *NewMI = buildInstr(Opcode, Ty);
MachineInstrBuilder(getMF(), NewMI).addMBB(&BB);
diff --git a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
index 8f97669a389..1148f5ce6f9 100644
--- a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
@@ -65,8 +65,7 @@ void RegisterBankInfo::createRegisterBank(unsigned ID, const char *Name) {
}
void RegisterBankInfo::addRegBankCoverage(unsigned ID, unsigned RCId,
- const TargetRegisterInfo &TRI,
- bool AddTypeMapping) {
+ const TargetRegisterInfo &TRI) {
RegisterBank &RB = getRegBank(ID);
unsigned NbOfRegClasses = TRI.getNumRegClasses();
@@ -98,13 +97,6 @@ void RegisterBankInfo::addRegBankCoverage(unsigned ID, unsigned RCId,
// Remember the biggest size in bits.
MaxSize = std::max(MaxSize, CurRC.getSize() * 8);
- // If we have been asked to record the type supported by this
- // register bank, do it now.
- if (AddTypeMapping)
- for (MVT::SimpleValueType SVT :
- make_range(CurRC.vt_begin(), CurRC.vt_end()))
- recordRegBankForType(getRegBank(ID), SVT);
-
// Walk through all sub register classes and push them into the worklist.
bool First = true;
for (BitMaskClassIterator It(CurRC.getSubClassMask(), TRI); It.isValid();
@@ -240,30 +232,18 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
// the register bank from the encoding constraints.
CurRegBank = getRegBankFromConstraints(MI, OpIdx, TII, TRI);
if (!CurRegBank) {
- // Check if we can deduce the register bank from the type of
- // the instruction.
- Type *MITy = MI.getType();
- if (MITy)
- CurRegBank = getRegBankForType(
- MVT::getVT(MITy, /*HandleUnknown*/ true).SimpleTy);
- if (!CurRegBank)
- // Use the current assigned register bank.
- // That may not make much sense though.
- CurRegBank = AltRegBank;
- if (!CurRegBank) {
- // All our attempts failed, give up.
- CompleteMapping = false;
-
- if (!isCopyLike)
- // MI does not carry enough information to guess the mapping.
- return InstructionMapping();
-
- // For copies, we want to keep interating to find a register
- // bank for the other operands if we did not find one yet.
- if (RegBank)
- break;
- continue;
- }
+ // All our attempts failed, give up.
+ CompleteMapping = false;
+
+ if (!isCopyLike)
+ // MI does not carry enough information to guess the mapping.
+ return InstructionMapping();
+
+ // For copies, we want to keep interating to find a register
+ // bank for the other operands if we did not find one yet.
+ if (RegBank)
+ break;
+ continue;
}
}
RegBank = CurRegBank;
diff --git a/llvm/lib/CodeGen/LowLevelType.cpp b/llvm/lib/CodeGen/LowLevelType.cpp
new file mode 100644
index 00000000000..0f696221e7c
--- /dev/null
+++ b/llvm/lib/CodeGen/LowLevelType.cpp
@@ -0,0 +1,46 @@
+//===-- llvm/CodeGen/GlobalISel/LowLevelType.cpp --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file This file implements the more header-heavy bits of the LLT class to
+/// avoid polluting users' namespaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/LowLevelType.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+LLT::LLT(const Type &Ty) {
+ if (auto VTy = dyn_cast<VectorType>(&Ty)) {
+ ScalarSize = VTy->getElementType()->getPrimitiveSizeInBits();
+ NumElements = VTy->getNumElements();
+ Kind = NumElements == 1 ? Scalar : Vector;
+ } else if (Ty.isSized()) {
+ // Aggregates are no different from real scalars as far as GlobalISel is
+ // concerned.
+ Kind = Scalar;
+ ScalarSize = Ty.getPrimitiveSizeInBits();
+ NumElements = 1;
+ } else {
+ Kind = Unsized;
+ ScalarSize = NumElements = 0;
+ }
+}
+
+void LLT::print(raw_ostream &OS) const {
+ if (isVector())
+ OS << "<" << NumElements << " x s" << ScalarSize << ">";
+ else if (isSized())
+ OS << "s" << ScalarSize;
+ else if (isValid())
+ OS << "unsized";
+ else
+ llvm_unreachable("trying to print an invalid type");
+}
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
index 6e3de52f1a9..c9b4135f822 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -173,14 +173,16 @@ static Cursor lexName(Cursor C, MIToken &Token, MIToken::TokenKind Type,
return C;
}
-static Cursor maybeLexIntegerType(Cursor C, MIToken &Token) {
- if (C.peek() != 'i' || !isdigit(C.peek(1)))
+static Cursor maybeLexIntegerOrScalarType(Cursor C, MIToken &Token) {
+ if ((C.peek() != 'i' && C.peek() != 's') || !isdigit(C.peek(1)))
return None;
+ char Kind = C.peek();
auto Range = C;
C.advance(); // Skip 'i'
while (isdigit(C.peek()))
C.advance();
- Token.reset(MIToken::IntegerType, Range.upto(C));
+ Token.reset(Kind == 'i' ? MIToken::IntegerType : MIToken::ScalarType,
+ Range.upto(C));
return C;
}
@@ -566,7 +568,7 @@ StringRef llvm::lexMIToken(StringRef Source, MIToken &Token,
return C.remaining();
}
- if (Cursor R = maybeLexIntegerType(C, Token))
+ if (Cursor R = maybeLexIntegerOrScalarType(C, Token))
return R.remaining();
if (Cursor R = maybeLexMachineBasicBlock(C, Token, ErrorCallback))
return R.remaining();
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h
index 32fc8ab271e..a5a95f82729 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.h
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -102,6 +102,7 @@ struct MIToken {
NamedRegister,
MachineBasicBlockLabel,
MachineBasicBlock,
+ ScalarType,
StackObject,
FixedStackObject,
NamedGlobalValue,
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 8937ee81c6a..e4ca9ae02f7 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -130,10 +130,8 @@ public:
bool parseIRConstant(StringRef::iterator Loc, StringRef Source,
const Constant *&C);
bool parseIRConstant(StringRef::iterator Loc, const Constant *&C);
- bool parseIRType(StringRef::iterator Loc, StringRef Source, unsigned &Read,
- Type *&Ty);
- // \p MustBeSized defines whether or not \p Ty must be sized.
- bool parseIRType(StringRef::iterator Loc, Type *&Ty, bool MustBeSized = true);
+ bool parseLowLevelType(StringRef::iterator Loc, LLT &Ty,
+ bool MustBeSized = true);
bool parseTypedImmediateOperand(MachineOperand &Dest);
bool parseFPImmediateOperand(MachineOperand &Dest);
bool parseMBBReference(MachineBasicBlock *&MBB);
@@ -597,11 +595,11 @@ bool MIParser::parse(MachineInstr *&MI) {
if (Token.isError() || parseInstruction(OpCode, Flags))
return true;
- Type *Ty = nullptr;
+ LLT Ty{};
if (isPreISelGenericOpcode(OpCode)) {
// For generic opcode, a type is mandatory.
auto Loc = Token.location();
- if (parseIRType(Loc, Ty))
+ if (parseLowLevelType(Loc, Ty))
return true;
}
@@ -660,7 +658,7 @@ bool MIParser::parse(MachineInstr *&MI) {
// TODO: Check for extraneous machine operands.
MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true);
MI->setFlags(Flags);
- if (Ty)
+ if (Ty.isValid())
MI->setType(Ty);
for (const auto &Operand : Operands)
MI->addOperand(MF, Operand.Operand);
@@ -1028,35 +1026,44 @@ bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) {
return false;
}
-bool MIParser::parseIRType(StringRef::iterator Loc, StringRef StringValue,
- unsigned &Read, Type *&Ty) {
- auto Source = StringValue.str(); // The source has to be null terminated.
- SMDiagnostic Err;
- Ty = parseTypeAtBeginning(Source.c_str(), Read, Err,
- *MF.getFunction()->getParent(), &PFS.IRSlots);
- if (!Ty)
- return error(Loc + Err.getColumnNo(), Err.getMessage());
- return false;
-}
+bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty,
+ bool MustBeSized) {
+ if (Token.is(MIToken::Identifier) && Token.stringValue() == "unsized") {
+ if (MustBeSized)
+ return error(Loc, "expected sN or <N x sM> for sized GlobalISel type");
+ lex();
+ Ty = LLT::unsized();
+ return false;
+ } else if (Token.is(MIToken::ScalarType)) {
+ Ty = LLT::scalar(APSInt(Token.range().drop_front()).getZExtValue());
+ lex();
+ return false;
+ }
-bool MIParser::parseIRType(StringRef::iterator Loc, Type *&Ty,
- bool MustBeSized) {
- // At this point we enter in the IR world, i.e., to get the correct type,
- // we need to hand off the whole string, not just the current token.
- // E.g., <4 x i64> would give '<' as a token and there is not much
- // the IR parser can do with that.
- unsigned Read = 0;
- if (parseIRType(Loc, StringRef(Loc), Read, Ty))
- return true;
- // The type must be sized, otherwise there is not much the backend
- // can do with it.
- if (MustBeSized && !Ty->isSized())
- return error("expected a sized type");
- // The next token is Read characters from the Loc.
- // However, the current location is not Loc, but Loc + the length of Token.
- // Therefore, subtract the length of Token (range().end() - Loc) to the
- // number of characters to skip before the next token.
- lex(Read - (Token.range().end() - Loc));
+ // Now we're looking for a vector.
+ if (Token.isNot(MIToken::less))
+ return error(Loc, "expected unsized, sN or <N x sM> for GlobalISel type");
+ lex();
+
+ if (Token.isNot(MIToken::IntegerLiteral))
+ return error(Loc, "expected <N x sM> for vctor type");
+ uint64_t NumElements = Token.integerValue().getZExtValue();
+ lex();
+
+ if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x")
+ return error(Loc, "expected '<N x sM>' for vector type");
+ lex();
+
+ if (Token.isNot(MIToken::ScalarType))
+ return error(Loc, "expected '<N x sM>' for vector type");
+ uint64_t ScalarSize = APSInt(Token.range().drop_front()).getZExtValue();
+ lex();
+
+ if (Token.isNot(MIToken::greater))
+ return error(Loc, "expected '<N x sM>' for vector type");
+ lex();
+
+ Ty = LLT::vector(NumElements, ScalarSize);
return false;
}
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index 703c99d9edd..bd06eec4d3c 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -565,9 +565,9 @@ void MIPrinter::print(const MachineInstr &MI) {
OS << "frame-setup ";
OS << TII->getName(MI.getOpcode());
if (isPreISelGenericOpcode(MI.getOpcode())) {
- assert(MI.getType() && "Generic instructions must have a type");
+ assert(MI.getType().isValid() && "Generic instructions must have a type");
OS << ' ';
- MI.getType()->print(OS, /*IsForDebug*/ false, /*NoDetails*/ true);
+ MI.getType().print(OS);
}
if (I < E)
OS << ' ';
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index 3cdf8d2941d..2ccfe259e9c 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -656,7 +656,7 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid,
debugLoc(std::move(dl))
#ifdef LLVM_BUILD_GLOBAL_ISEL
,
- Ty(nullptr)
+ Ty(LLT{})
#endif
{
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
@@ -680,7 +680,7 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
MemRefs(MI.MemRefs), debugLoc(MI.getDebugLoc())
#ifdef LLVM_BUILD_GLOBAL_ISEL
,
- Ty(nullptr)
+ Ty(LLT{})
#endif
{
assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
@@ -710,18 +710,18 @@ MachineRegisterInfo *MachineInstr::getRegInfo() {
// The proper implementation is WIP and is tracked here:
// PR26576.
#ifndef LLVM_BUILD_GLOBAL_ISEL
-void MachineInstr::setType(Type *Ty) {}
+void MachineInstr::setType(LLT Ty) {}
-Type *MachineInstr::getType() const { return nullptr; }
+LLT MachineInstr::getType() const { return LLT{}; }
#else
-void MachineInstr::setType(Type *Ty) {
- assert((!Ty || isPreISelGenericOpcode(getOpcode())) &&
+void MachineInstr::setType(LLT Ty) {
+ assert((!Ty.isValid() || isPreISelGenericOpcode(getOpcode())) &&
"Non generic instructions are not supposed to be typed");
this->Ty = Ty;
}
-Type *MachineInstr::getType() const { return Ty; }
+LLT MachineInstr::getType() const { return Ty; }
#endif // LLVM_BUILD_GLOBAL_ISEL
/// RemoveRegOperandsFromUseLists - Unlink all of the register operands in
@@ -1724,9 +1724,9 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
else
OS << "UNKNOWN";
- if (getType()) {
+ if (getType().isValid()) {
OS << ' ';
- getType()->print(OS, /*IsForDebug*/ false, /*NoDetails*/ true);
+ getType().print(OS);
OS << ' ';
}
OpenPOWER on IntegriCloud