diff options
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp | 46 | ||||
-rw-r--r-- | llvm/lib/CodeGen/LowLevelType.cpp | 46 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MILexer.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MILexer.h | 1 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 77 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MIRPrinter.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MachineInstr.cpp | 18 |
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 << ' '; } |