From: Nicolai Haehnle Date: Tue, 6 Mar 2018 13:48:30 +0000 (+0000) Subject: TableGen: Simplify BitsInit::resolveReferences X-Git-Tag: llvmorg-7.0.0-rc1~11335 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9a84a509130c1c6501655f89ce43b9e7d37a2bb4;p=platform%2Fupstream%2Fllvm.git TableGen: Simplify BitsInit::resolveReferences Summary: No functional change intended. The removed code has a loop for recursive resolving, which is superseded by the recursive resolving done by the Resolver implementations. Add a test case which was broken by an earlier version of this change. Change-Id: Ib208d037b77a8bbb725977f1388601fc984723d8 Reviewers: arsenm, craig.topper, tra, MartinO Subscribers: wdng, llvm-commits Differential Revision: https://reviews.llvm.org/D43655 llvm-svn: 326784 --- diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h index 5ab6636..fdda543 100644 --- a/llvm/include/llvm/TableGen/Record.h +++ b/llvm/include/llvm/TableGen/Record.h @@ -391,14 +391,6 @@ public: /// This method is used to return the initializer for the specified /// bit. virtual Init *getBit(unsigned Bit) const = 0; - - /// This method is used to retrieve the initializer for bit - /// reference. For non-VarBitInit, it simply returns itself. - virtual Init *getBitVar() const { return const_cast(this); } - - /// This method is used to retrieve the bit number of a bit - /// reference. For non-VarBitInit, it simply returns 0. - virtual unsigned getBitNum() const { return 0; } }; inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) { @@ -954,8 +946,8 @@ public: Init *convertInitializerTo(RecTy *Ty) const override; - Init *getBitVar() const override { return TI; } - unsigned getBitNum() const override { return Bit; } + Init *getBitVar() const { return TI; } + unsigned getBitNum() const { return Bit; } std::string getAsString() const override; Init *resolveReferences(Resolver &R) const override; diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index 7bd8d45..a2f586c 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -393,54 +393,35 @@ std::string BitsInit::getAsString() const { return Result + " }"; } -// Fix bit initializer to preserve the behavior that bit reference from a unset -// bits initializer will resolve into VarBitInit to keep the field name and bit -// number used in targets with fixed insn length. -static Init *fixBitInit(const Resolver &R, Init *Before, Init *After) { - if (!isa(After) || !R.keepUnsetBits()) - return After; - return Before; -} - // resolveReferences - If there are any field references that refer to fields // that have been filled in, we can propagate the values now. Init *BitsInit::resolveReferences(Resolver &R) const { bool Changed = false; SmallVector NewBits(getNumBits()); - Init *CachedInit = nullptr; - Init *CachedBitVar = nullptr; - bool CachedBitVarChanged = false; + Init *CachedBitVarRef = nullptr; + Init *CachedBitVarResolved = nullptr; for (unsigned i = 0, e = getNumBits(); i != e; ++i) { Init *CurBit = getBit(i); - Init *CurBitVar = CurBit->getBitVar(); + Init *NewBit = CurBit; - NewBits[i] = CurBit; - - if (CurBitVar == CachedBitVar) { - if (CachedBitVarChanged) { - Init *Bit = CachedInit->getBit(CurBit->getBitNum()); - NewBits[i] = fixBitInit(R, CurBit, Bit); + if (VarBitInit *CurBitVar = dyn_cast(CurBit)) { + if (CurBitVar->getBitVar() != CachedBitVarRef) { + CachedBitVarRef = CurBitVar->getBitVar(); + CachedBitVarResolved = CachedBitVarRef->resolveReferences(R); } - continue; - } - CachedBitVar = CurBitVar; - CachedBitVarChanged = false; - Init *B; - do { - B = CurBitVar; - CurBitVar = CurBitVar->resolveReferences(R); - CachedBitVarChanged |= B != CurBitVar; - Changed |= B != CurBitVar; - } while (B != CurBitVar); - CachedInit = CurBitVar; - - if (CachedBitVarChanged) { - Init *Bit = CurBitVar->getBit(CurBit->getBitNum()); - NewBits[i] = fixBitInit(R, CurBit, Bit); + NewBit = CachedBitVarResolved->getBit(CurBitVar->getBitNum()); + } else { + // getBit(0) implicitly converts int and bits<1> values to bit. + NewBit = CurBit->resolveReferences(R)->getBit(0); } + + if (isa(NewBit) && R.keepUnsetBits()) + NewBit = CurBit; + NewBits[i] = NewBit; + Changed |= CurBit != NewBit; } if (Changed) diff --git a/llvm/test/TableGen/UnsetBitInit.td b/llvm/test/TableGen/UnsetBitInit.td index d232293..6948473 100644 --- a/llvm/test/TableGen/UnsetBitInit.td +++ b/llvm/test/TableGen/UnsetBitInit.td @@ -1,5 +1,34 @@ -// RUN: llvm-tblgen %s +// RUN: llvm-tblgen %s | FileCheck %s // XFAIL: vg_leak + +// CHECK: --- Defs --- + +// Test that P and Q are not replaced by ?. TableGen's codegen emitter backend +// relies on keeping variable references like this around to describe the +// structure of instruction encodings. +// +// CHECK: def A { +// CHECK: bits<8> Inst = { 1, 1, 1, 1, 1, 1, P, Q }; +// CHECK: bits<2> src = { ?, ? }; +// CHECK: bit P = ?; +// CHECK: bit Q = ?; +// CHECK: } + +def A { + bits<8> Inst; + bits<2> src; + + bit P; + bit Q; + + let Inst{7-2} = 0x3f; + let Inst{1} = P; + let Inst{0} = Q; + + let P = src{1}; + let Q = src{0}; +} + class x { field bits<32> A; }