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
|
/// This method is used to return the initializer for the specified
|
||||||
/// bit.
|
/// bit.
|
||||||
virtual Init *getBit(unsigned Bit) const = 0;
|
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) {
|
inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) {
|
||||||
|
@ -954,8 +946,8 @@ public:
|
||||||
|
|
||||||
Init *convertInitializerTo(RecTy *Ty) const override;
|
Init *convertInitializerTo(RecTy *Ty) const override;
|
||||||
|
|
||||||
Init *getBitVar() const override { return TI; }
|
Init *getBitVar() const { return TI; }
|
||||||
unsigned getBitNum() const override { return Bit; }
|
unsigned getBitNum() const { return Bit; }
|
||||||
|
|
||||||
std::string getAsString() const override;
|
std::string getAsString() const override;
|
||||||
Init *resolveReferences(Resolver &R) const override;
|
Init *resolveReferences(Resolver &R) const override;
|
||||||
|
|
|
@ -393,54 +393,35 @@ std::string BitsInit::getAsString() const {
|
||||||
return Result + " }";
|
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
|
// resolveReferences - If there are any field references that refer to fields
|
||||||
// that have been filled in, we can propagate the values now.
|
// that have been filled in, we can propagate the values now.
|
||||||
Init *BitsInit::resolveReferences(Resolver &R) const {
|
Init *BitsInit::resolveReferences(Resolver &R) const {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
SmallVector<Init *, 16> NewBits(getNumBits());
|
SmallVector<Init *, 16> NewBits(getNumBits());
|
||||||
|
|
||||||
Init *CachedInit = nullptr;
|
Init *CachedBitVarRef = nullptr;
|
||||||
Init *CachedBitVar = nullptr;
|
Init *CachedBitVarResolved = nullptr;
|
||||||
bool CachedBitVarChanged = false;
|
|
||||||
|
|
||||||
for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
|
for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
|
||||||
Init *CurBit = getBit(i);
|
Init *CurBit = getBit(i);
|
||||||
Init *CurBitVar = CurBit->getBitVar();
|
Init *NewBit = CurBit;
|
||||||
|
|
||||||
NewBits[i] = CurBit;
|
if (VarBitInit *CurBitVar = dyn_cast<VarBitInit>(CurBit)) {
|
||||||
|
if (CurBitVar->getBitVar() != CachedBitVarRef) {
|
||||||
if (CurBitVar == CachedBitVar) {
|
CachedBitVarRef = CurBitVar->getBitVar();
|
||||||
if (CachedBitVarChanged) {
|
CachedBitVarResolved = CachedBitVarRef->resolveReferences(R);
|
||||||
Init *Bit = CachedInit->getBit(CurBit->getBitNum());
|
|
||||||
NewBits[i] = fixBitInit(R, CurBit, Bit);
|
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CachedBitVar = CurBitVar;
|
|
||||||
CachedBitVarChanged = false;
|
|
||||||
|
|
||||||
Init *B;
|
NewBit = CachedBitVarResolved->getBit(CurBitVar->getBitNum());
|
||||||
do {
|
} else {
|
||||||
B = CurBitVar;
|
// getBit(0) implicitly converts int and bits<1> values to bit.
|
||||||
CurBitVar = CurBitVar->resolveReferences(R);
|
NewBit = CurBit->resolveReferences(R)->getBit(0);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isa<UnsetInit>(NewBit) && R.keepUnsetBits())
|
||||||
|
NewBit = CurBit;
|
||||||
|
NewBits[i] = NewBit;
|
||||||
|
Changed |= CurBit != NewBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Changed)
|
if (Changed)
|
||||||
|
|
|
@ -1,5 +1,34 @@
|
||||||
// RUN: llvm-tblgen %s
|
// RUN: llvm-tblgen %s | FileCheck %s
|
||||||
// XFAIL: vg_leak
|
// 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 {
|
class x {
|
||||||
field bits<32> A;
|
field bits<32> A;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue