summaryrefslogtreecommitdiffstats
path: root/llvm/lib/TableGen/Record.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/TableGen/Record.cpp')
-rw-r--r--llvm/lib/TableGen/Record.cpp131
1 files changed, 131 insertions, 0 deletions
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 79f8907d4b5..ab3dfce5e84 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -1693,6 +1693,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) {
OpenPOWER on IntegriCloud