aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/TableGen/Record.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/TableGen/Record.cpp')
-rw-r--r--contrib/llvm/lib/TableGen/Record.cpp204
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) {