diff options
Diffstat (limited to 'contrib/llvm/lib/TableGen/Record.cpp')
-rw-r--r-- | contrib/llvm/lib/TableGen/Record.cpp | 204 |
1 files changed, 192 insertions, 12 deletions
diff --git a/contrib/llvm/lib/TableGen/Record.cpp b/contrib/llvm/lib/TableGen/Record.cpp index cf1685a2e8c2..27d1bdc7f4c3 100644 --- a/contrib/llvm/lib/TableGen/Record.cpp +++ b/contrib/llvm/lib/TableGen/Record.cpp @@ -1,9 +1,8 @@ //===- Record.cpp - Record implementation ---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -16,9 +15,11 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" @@ -31,14 +32,20 @@ #include <cassert> #include <cstdint> #include <memory> +#include <map> #include <string> #include <utility> #include <vector> using namespace llvm; +#define DEBUG_TYPE "tblgen-records" + static BumpPtrAllocator Allocator; +STATISTIC(CodeInitsConstructed, + "The total number of unique CodeInits constructed"); + //===----------------------------------------------------------------------===// // Type implementations //===----------------------------------------------------------------------===// @@ -451,7 +458,7 @@ Init *BitsInit::resolveReferences(Resolver &R) const { } IntInit *IntInit::get(int64_t V) { - static DenseMap<int64_t, IntInit*> ThePool; + static std::map<int64_t, IntInit*> ThePool; IntInit *&I = ThePool[V]; if (!I) I = new(Allocator) IntInit(V); @@ -507,13 +514,20 @@ IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const { return BitsInit::get(NewBits); } -CodeInit *CodeInit::get(StringRef V) { - static StringMap<CodeInit*, BumpPtrAllocator &> ThePool(Allocator); +CodeInit *CodeInit::get(StringRef V, const SMLoc &Loc) { + static StringSet<BumpPtrAllocator &> ThePool(Allocator); - auto &Entry = *ThePool.insert(std::make_pair(V, nullptr)).first; - if (!Entry.second) - Entry.second = new(Allocator) CodeInit(Entry.getKey()); - return Entry.second; + CodeInitsConstructed++; + + // Unlike StringMap, StringSet doesn't accept empty keys. + if (V.empty()) + return new (Allocator) CodeInit("", Loc); + + // Location tracking prevents us from de-duping CodeInits as we're never + // called with the same string and same location twice. However, we can at + // least de-dupe the strings for a modest saving. + auto &Entry = *ThePool.insert(V).first; + return new(Allocator) CodeInit(Entry.getKey(), Loc); } StringInit *StringInit::get(StringRef V) { @@ -529,7 +543,7 @@ Init *StringInit::convertInitializerTo(RecTy *Ty) const { if (isa<StringRecTy>(Ty)) return const_cast<StringInit *>(this); if (isa<CodeRecTy>(Ty)) - return CodeInit::get(getValue()); + return CodeInit::get(getValue(), SMLoc()); return nullptr; } @@ -843,6 +857,28 @@ Init *BinOpInit::getStrConcat(Init *I0, Init *I1) { return BinOpInit::get(BinOpInit::STRCONCAT, I0, I1, StringRecTy::get()); } +static ListInit *ConcatListInits(const ListInit *LHS, + const ListInit *RHS) { + SmallVector<Init *, 8> Args; + Args.insert(Args.end(), LHS->begin(), LHS->end()); + Args.insert(Args.end(), RHS->begin(), RHS->end()); + return ListInit::get(Args, LHS->getElementType()); +} + +Init *BinOpInit::getListConcat(TypedInit *LHS, Init *RHS) { + assert(isa<ListRecTy>(LHS->getType()) && "First arg must be a list"); + + // Shortcut for the common case of concatenating two lists. + if (const ListInit *LHSList = dyn_cast<ListInit>(LHS)) + if (const ListInit *RHSList = dyn_cast<ListInit>(RHS)) + return ConcatListInits(LHSList, RHSList); + return BinOpInit::get(BinOpInit::LISTCONCAT, LHS, RHS, LHS->getType()); +} + +Init *BinOpInit::getListSplat(TypedInit *LHS, Init *RHS) { + return BinOpInit::get(BinOpInit::LISTSPLAT, LHS, RHS, LHS->getType()); +} + Init *BinOpInit::Fold(Record *CurRec) const { switch (getOpcode()) { case CONCAT: { @@ -883,6 +919,15 @@ Init *BinOpInit::Fold(Record *CurRec) const { } break; } + case LISTSPLAT: { + TypedInit *Value = dyn_cast<TypedInit>(LHS); + IntInit *Size = dyn_cast<IntInit>(RHS); + if (Value && Size) { + SmallVector<Init *, 8> Args(Size->getValue(), Value); + return ListInit::get(Args, Value->getType()); + } + break; + } case STRCONCAT: { StringInit *LHSs = dyn_cast<StringInit>(LHS); StringInit *RHSs = dyn_cast<StringInit>(RHS); @@ -931,6 +976,7 @@ Init *BinOpInit::Fold(Record *CurRec) const { break; } case ADD: + case MUL: case AND: case OR: case SHL: @@ -946,6 +992,7 @@ Init *BinOpInit::Fold(Record *CurRec) const { switch (getOpcode()) { default: llvm_unreachable("Bad opcode!"); case ADD: Result = LHSv + RHSv; break; + case MUL: Result = LHSv * RHSv; break; case AND: Result = LHSv & RHSv; break; case OR: Result = LHSv | RHSv; break; case SHL: Result = LHSv << RHSv; break; @@ -975,6 +1022,7 @@ std::string BinOpInit::getAsString() const { switch (getOpcode()) { case CONCAT: Result = "!con"; break; case ADD: Result = "!add"; break; + case MUL: Result = "!mul"; break; case AND: Result = "!and"; break; case OR: Result = "!or"; break; case SHL: Result = "!shl"; break; @@ -987,6 +1035,7 @@ std::string BinOpInit::getAsString() const { case GE: Result = "!ge"; break; case GT: Result = "!gt"; break; case LISTCONCAT: Result = "!listconcat"; break; + case LISTSPLAT: Result = "!listsplat"; break; case STRCONCAT: Result = "!strconcat"; break; } return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")"; @@ -1694,6 +1743,137 @@ Init *FieldInit::Fold(Record *CurRec) const { return const_cast<FieldInit *>(this); } +static void ProfileCondOpInit(FoldingSetNodeID &ID, + ArrayRef<Init *> CondRange, + ArrayRef<Init *> ValRange, + const RecTy *ValType) { + assert(CondRange.size() == ValRange.size() && + "Number of conditions and values must match!"); + ID.AddPointer(ValType); + ArrayRef<Init *>::iterator Case = CondRange.begin(); + ArrayRef<Init *>::iterator Val = ValRange.begin(); + + while (Case != CondRange.end()) { + ID.AddPointer(*Case++); + ID.AddPointer(*Val++); + } +} + +void CondOpInit::Profile(FoldingSetNodeID &ID) const { + ProfileCondOpInit(ID, + makeArrayRef(getTrailingObjects<Init *>(), NumConds), + makeArrayRef(getTrailingObjects<Init *>() + NumConds, NumConds), + ValType); +} + +CondOpInit * +CondOpInit::get(ArrayRef<Init *> CondRange, + ArrayRef<Init *> ValRange, RecTy *Ty) { + assert(CondRange.size() == ValRange.size() && + "Number of conditions and values must match!"); + + static FoldingSet<CondOpInit> ThePool; + FoldingSetNodeID ID; + ProfileCondOpInit(ID, CondRange, ValRange, Ty); + + void *IP = nullptr; + if (CondOpInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) + return I; + + void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *>(2*CondRange.size()), + alignof(BitsInit)); + CondOpInit *I = new(Mem) CondOpInit(CondRange.size(), Ty); + + std::uninitialized_copy(CondRange.begin(), CondRange.end(), + I->getTrailingObjects<Init *>()); + std::uninitialized_copy(ValRange.begin(), ValRange.end(), + I->getTrailingObjects<Init *>()+CondRange.size()); + ThePool.InsertNode(I, IP); + return I; +} + +Init *CondOpInit::resolveReferences(Resolver &R) const { + SmallVector<Init*, 4> NewConds; + bool Changed = false; + for (const Init *Case : getConds()) { + Init *NewCase = Case->resolveReferences(R); + NewConds.push_back(NewCase); + Changed |= NewCase != Case; + } + + SmallVector<Init*, 4> NewVals; + for (const Init *Val : getVals()) { + Init *NewVal = Val->resolveReferences(R); + NewVals.push_back(NewVal); + Changed |= NewVal != Val; + } + + if (Changed) + return (CondOpInit::get(NewConds, NewVals, + getValType()))->Fold(R.getCurrentRecord()); + + return const_cast<CondOpInit *>(this); +} + +Init *CondOpInit::Fold(Record *CurRec) const { + for ( unsigned i = 0; i < NumConds; ++i) { + Init *Cond = getCond(i); + Init *Val = getVal(i); + + if (IntInit *CondI = dyn_cast_or_null<IntInit>( + Cond->convertInitializerTo(IntRecTy::get()))) { + if (CondI->getValue()) + return Val->convertInitializerTo(getValType()); + } else + return const_cast<CondOpInit *>(this); + } + + PrintFatalError(CurRec->getLoc(), + CurRec->getName() + + " does not have any true condition in:" + + this->getAsString()); + return nullptr; +} + +bool CondOpInit::isConcrete() const { + for (const Init *Case : getConds()) + if (!Case->isConcrete()) + return false; + + for (const Init *Val : getVals()) + if (!Val->isConcrete()) + return false; + + return true; +} + +bool CondOpInit::isComplete() const { + for (const Init *Case : getConds()) + if (!Case->isComplete()) + return false; + + for (const Init *Val : getVals()) + if (!Val->isConcrete()) + return false; + + return true; +} + +std::string CondOpInit::getAsString() const { + std::string Result = "!cond("; + for (unsigned i = 0; i < getNumConds(); i++) { + Result += getCond(i)->getAsString() + ": "; + Result += getVal(i)->getAsString(); + if (i != getNumConds()-1) + Result += ", "; + } + return Result + ")"; +} + +Init *CondOpInit::getBit(unsigned Bit) const { + return VarBitInit::get(const_cast<CondOpInit *>(this), Bit); +} + static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, StringInit *VN, ArrayRef<Init *> ArgRange, ArrayRef<StringInit *> NameRange) { |