TableGen: Factor out STRCONCAT constructor, add shortcut.

Introduce new constructor for STRCONCAT binop with a shortcut that
immediately concatenates if the two arguments are StringInits.
Makes the QualifyName code more readable and tablegen 2-3% faster.

llvm-svn: 288639
This commit is contained in:
Matthias Braun 2016-12-05 05:21:18 +00:00
parent b1627ff0c8
commit 6e074de48e
1 changed files with 25 additions and 26 deletions

View File

@ -813,6 +813,13 @@ void BinOpInit::Profile(FoldingSetNodeID &ID) const {
ProfileBinOpInit(ID, getOpcode(), getLHS(), getRHS(), getType()); ProfileBinOpInit(ID, getOpcode(), getLHS(), getRHS(), getType());
} }
static StringInit *ConcatStringInits(const StringInit *I0,
const StringInit *I1) {
SmallString<80> Concat(I0->getValue());
Concat.append(I1->getValue());
return StringInit::get(Concat);
}
Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
switch (getOpcode()) { switch (getOpcode()) {
case CONCAT: { case CONCAT: {
@ -852,12 +859,8 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
case STRCONCAT: { case STRCONCAT: {
StringInit *LHSs = dyn_cast<StringInit>(LHS); StringInit *LHSs = dyn_cast<StringInit>(LHS);
StringInit *RHSs = dyn_cast<StringInit>(RHS); StringInit *RHSs = dyn_cast<StringInit>(RHS);
if (LHSs && RHSs) { if (LHSs && RHSs)
// STRCONCAT is common; Use a SmallString to avoid most heap allocations. return ConcatStringInits(LHSs, RHSs);
SmallString<80> Concat(LHSs->getValue());
Concat.append(RHSs->getValue());
return StringInit::get(Concat);
}
break; break;
} }
case EQ: { case EQ: {
@ -1940,31 +1943,27 @@ RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const {
return Defs; return Defs;
} }
static Init *GetStrConcat(Init *I0, Init *I1) {
// Shortcut for the common case of concatenating two strings.
if (const StringInit *I0s = dyn_cast<StringInit>(I0))
if (const StringInit *I1s = dyn_cast<StringInit>(I1))
return ConcatStringInits(I0s, I1s);
return BinOpInit::get(BinOpInit::STRCONCAT, I0, I1, StringRecTy::get());
}
Init *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass, Init *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass,
Init *Name, StringRef Scoper) { Init *Name, StringRef Scoper) {
RecTy *Type = cast<TypedInit>(Name)->getType(); Init *NewName = GetStrConcat(CurRec.getNameInit(), StringInit::get(Scoper));
NewName = GetStrConcat(NewName, Name);
BinOpInit *NewName =
BinOpInit::get(BinOpInit::STRCONCAT,
BinOpInit::get(BinOpInit::STRCONCAT,
CurRec.getNameInit(),
StringInit::get(Scoper),
Type)->Fold(&CurRec, CurMultiClass),
Name,
Type);
if (CurMultiClass && Scoper != "::") { if (CurMultiClass && Scoper != "::") {
NewName = Init *Prefix = GetStrConcat(CurMultiClass->Rec.getNameInit(),
BinOpInit::get(BinOpInit::STRCONCAT, StringInit::get("::"));
BinOpInit::get(BinOpInit::STRCONCAT, NewName = GetStrConcat(Prefix, NewName);
CurMultiClass->Rec.getNameInit(),
StringInit::get("::"),
Type)->Fold(&CurRec, CurMultiClass),
NewName->Fold(&CurRec, CurMultiClass),
Type);
} }
return NewName->Fold(&CurRec, CurMultiClass); if (BinOpInit *BinOp = dyn_cast<BinOpInit>(NewName))
NewName = BinOp->Fold(&CurRec, CurMultiClass);
return NewName;
} }
Init *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass, Init *llvm::QualifyName(Record &CurRec, MultiClass *CurMultiClass,