diff options
author | Nicolai Haehnle <nhaehnle@gmail.com> | 2018-02-25 20:50:04 +0000 |
---|---|---|
committer | Nicolai Haehnle <nhaehnle@gmail.com> | 2018-02-25 20:50:04 +0000 |
commit | 801403acb358d3388636d3b36f28839758507306 (patch) | |
tree | 4e28510a77fc1306cc97b7ae89f044171d0d40a7 /llvm/lib/TableGen | |
parent | 836684aff3aeacb981ff500622d98981e9ac89ae (diff) | |
download | bcm5719-llvm-801403acb358d3388636d3b36f28839758507306.tar.gz bcm5719-llvm-801403acb358d3388636d3b36f28839758507306.zip |
TableGen: Remove Init::resolveListElementReference
Summary:
Resolving a VarListElementInit should just resolve the list and then
take its element. This eliminates a lot of duplicated logic and
simplifies the next steps of refactoring resolveReferences.
This does potentially cause sub-elements of the entire list to be
resolved resulting in more work, but I didn't notice a measurable
change in performance, and a later patch adds a caching mechanism that
covers at least the common case of `var[i]` in a more generic way.
Change-Id: I7b59185b855c7368585c329c31e5be38c5749dac
Reviewers: arsenm, craig.topper, tra, MartinO
Subscribers: wdng, llvm-commits
Differential Revision: https://reviews.llvm.org/D43562
llvm-svn: 326059
Diffstat (limited to 'llvm/lib/TableGen')
-rw-r--r-- | llvm/lib/TableGen/Record.cpp | 97 |
1 files changed, 9 insertions, 88 deletions
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index 80c0973644b..2650eca2cc0 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -564,19 +564,6 @@ Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) const { return const_cast<ListInit *>(this); } -Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV, - unsigned Elt) const { - if (Elt >= size()) - return nullptr; // Out of range reference. - Init *E = getElement(Elt); - // If the element is set to some value, or if we are resolving a reference - // to a specific variable and that variable is explicitly unset, then - // replace the VarListElementInit with it. - if (IRV || !isa<UnsetInit>(E)) - return E; - return nullptr; -} - std::string ListInit::getAsString() const { std::string Result = "["; const char *sep = ""; @@ -588,24 +575,6 @@ std::string ListInit::getAsString() const { return Result + "]"; } -Init *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV, - unsigned Elt) const { - Init *Resolved = resolveReferences(R, IRV); - OpInit *OResolved = dyn_cast<OpInit>(Resolved); - if (OResolved) { - Resolved = OResolved->Fold(&R, nullptr); - } - - if (Resolved != this) { - TypedInit *Typed = cast<TypedInit>(Resolved); - if (Init *New = Typed->resolveListElementReference(R, IRV, Elt)) - return New; - return VarListElementInit::get(Typed, Elt); - } - - return nullptr; -} - Init *OpInit::getBit(unsigned Bit) const { if (getType() == BitRecTy::get()) return const_cast<OpInit*>(this); @@ -1279,29 +1248,6 @@ Init *VarInit::getBit(unsigned Bit) const { return VarBitInit::get(const_cast<VarInit*>(this), Bit); } -Init *VarInit::resolveListElementReference(Record &R, - const RecordVal *IRV, - unsigned Elt) const { - if (R.isTemplateArg(getNameInit())) return nullptr; - if (IRV && IRV->getNameInit() != getNameInit()) return nullptr; - - RecordVal *RV = R.getValue(getNameInit()); - assert(RV && "Reference to a non-existent variable?"); - ListInit *LI = dyn_cast<ListInit>(RV->getValue()); - if (!LI) - return VarListElementInit::get(cast<TypedInit>(RV->getValue()), Elt); - - if (Elt >= LI->size()) - return nullptr; // Out of range reference. - Init *E = LI->getElement(Elt); - // If the element is set to some value, or if we are resolving a reference - // to a specific variable and that variable is explicitly unset, then - // replace the VarListElementInit with it. - if (IRV || !isa<UnsetInit>(E)) - return E; - return nullptr; -} - RecTy *VarInit::getFieldType(StringInit *FieldName) const { if (RecordRecTy *RTy = dyn_cast<RecordRecTy>(getType())) if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName)) @@ -1380,9 +1326,15 @@ std::string VarListElementInit::getAsString() const { Init * VarListElementInit::resolveReferences(Record &R, const RecordVal *RV) const { - if (Init *I = getVariable()->resolveListElementReference(R, RV, - getElementNum())) - return I; + Init *NewTI = TI->resolveReferences(R, RV); + if (ListInit *List = dyn_cast<ListInit>(NewTI)) { + // Leave out-of-bounds array references as-is. This can happen without + // being an error, e.g. in the untaken "branch" of an !if expression. + if (getElementNum() < List->size()) + return List->getElement(getElementNum()); + } + if (NewTI != TI && isa<TypedInit>(NewTI)) + return VarListElementInit::get(cast<TypedInit>(NewTI), getElementNum()); return const_cast<VarListElementInit *>(this); } @@ -1392,21 +1344,6 @@ Init *VarListElementInit::getBit(unsigned Bit) const { return VarBitInit::get(const_cast<VarListElementInit*>(this), Bit); } -Init *VarListElementInit:: resolveListElementReference(Record &R, - const RecordVal *RV, - unsigned Elt) const { - if (Init *Result = TI->resolveListElementReference(R, RV, Element)) { - if (TypedInit *TInit = dyn_cast<TypedInit>(Result)) { - if (Init *Result2 = TInit->resolveListElementReference(R, RV, Elt)) - return Result2; - return VarListElementInit::get(TInit, Elt); - } - return Result; - } - - return nullptr; -} - DefInit *DefInit::get(Record *R) { return R->getDefInit(); } @@ -1450,22 +1387,6 @@ Init *FieldInit::getBit(unsigned Bit) const { return VarBitInit::get(const_cast<FieldInit*>(this), Bit); } -Init *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV, - unsigned Elt) const { - if (Init *ListVal = Rec->getFieldInit(R, RV, FieldName)) - if (ListInit *LI = dyn_cast<ListInit>(ListVal)) { - if (Elt >= LI->size()) return nullptr; - Init *E = LI->getElement(Elt); - - // If the element is set to some value, or if we are resolving a - // reference to a specific variable and that variable is explicitly - // unset, then replace the VarListElementInit with it. - if (RV || !isa<UnsetInit>(E)) - return E; - } - return nullptr; -} - Init *FieldInit::resolveReferences(Record &R, const RecordVal *RV) const { Init *NewRec = RV ? Rec->resolveReferences(R, RV) : Rec; |