forked from OSchip/llvm-project
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
This commit is contained in:
parent
13080fd14e
commit
9a84a50913
|
@ -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<Init*>(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;
|
||||
|
|
|
@ -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<UnsetInit>(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<Init *, 16> 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<VarBitInit>(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<UnsetInit>(NewBit) && R.keepUnsetBits())
|
||||
NewBit = CurBit;
|
||||
NewBits[i] = NewBit;
|
||||
Changed |= CurBit != NewBit;
|
||||
}
|
||||
|
||||
if (Changed)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue