Optimized usage of new SwitchInst case values (IntegersSubset type) in Local.cpp, Execution.cpp and BitcodeWriter.cpp.

I got about 1% of compile-time improvement on my machines (Ubuntu 11.10 i386 and Ubuntu 12.04 x64).



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159076 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Stepan Dyatkovskiy 2012-06-23 10:58:58 +00:00
parent fc76b8691e
commit 47cbc4e0ee
4 changed files with 64 additions and 27 deletions

View File

@ -2705,8 +2705,7 @@ public:
}
/// Resolves case value for current case.
// IntegersSubsetRef getCaseValueEx() {
IntegersSubset getCaseValueEx() {
IntegersSubsetRef getCaseValueEx() {
assert(Index < SI->getNumCases() && "Index out the number of cases.");
return *SubsetIt;
}

View File

@ -1157,19 +1157,38 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
Vals64.push_back(SI.getNumCases());
for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end();
i != e; ++i) {
IntegersSubset CaseRanges = i.getCaseValueEx();
Vals64.push_back(CaseRanges.getNumItems());
for (unsigned ri = 0, rn = CaseRanges.getNumItems(); ri != rn; ++ri) {
IntegersSubset::Range r = CaseRanges.getItem(ri);
bool IsSingleNumber = r.isSingleNumber();
Vals64.push_back(IsSingleNumber);
unsigned Code, Abbrev; // will unused.
IntegersSubset& CaseRanges = i.getCaseValueEx();
unsigned Code, Abbrev; // will unused.
if (CaseRanges.isSingleNumber()) {
Vals64.push_back(1/*NumItems = 1*/);
Vals64.push_back(true/*IsSingleNumber = true*/);
EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(0), true);
} else {
EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
if (!IsSingleNumber)
EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
Vals64.push_back(CaseRanges.getNumItems());
if (CaseRanges.isSingleNumbersOnly()) {
for (unsigned ri = 0, rn = CaseRanges.getNumItems();
ri != rn; ++ri) {
Vals64.push_back(true/*IsSingleNumber = true*/);
EmitAPInt(Vals64, Code, Abbrev,
CaseRanges.getSingleNumber(ri), true);
}
} else
for (unsigned ri = 0, rn = CaseRanges.getNumItems();
ri != rn; ++ri) {
IntegersSubset::Range r = CaseRanges.getItem(ri);
bool IsSingleNumber = CaseRanges.isSingleNumber(ri);
Vals64.push_back(IsSingleNumber);
EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
if (!IsSingleNumber)
EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
}
}
Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
}

View File

@ -651,20 +651,40 @@ void Interpreter::visitSwitchInst(SwitchInst &I) {
// Check to see if any of the cases match...
BasicBlock *Dest = 0;
for (SwitchInst::CaseIt i = I.case_begin(), e = I.case_end(); i != e; ++i) {
IntegersSubset Case = i.getCaseValueEx();
for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
IntegersSubset::Range r = Case.getItem(n);
IntegersSubset& Case = i.getCaseValueEx();
if (Case.isSingleNumber()) {
// FIXME: Currently work with ConstantInt based numbers.
const ConstantInt *LowCI = r.getLow().toConstantInt();
const ConstantInt *HighCI = r.getHigh().toConstantInt();
GenericValue Low = getOperandValue(const_cast<ConstantInt*>(LowCI), SF);
GenericValue High = getOperandValue(const_cast<ConstantInt*>(HighCI), SF);
if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 &&
executeICMP_ULE(CondVal, High, ElTy).IntVal != 0) {
const ConstantInt *CI = Case.getSingleNumber(0).toConstantInt();
GenericValue Val = getOperandValue(const_cast<ConstantInt*>(CI), SF);
if (executeICMP_EQ(Val, CondVal, ElTy).IntVal != 0) {
Dest = cast<BasicBlock>(i.getCaseSuccessor());
break;
}
}
if (Case.isSingleNumbersOnly()) {
for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
// FIXME: Currently work with ConstantInt based numbers.
const ConstantInt *CI = Case.getSingleNumber(n).toConstantInt();
GenericValue Val = getOperandValue(const_cast<ConstantInt*>(CI), SF);
if (executeICMP_EQ(Val, CondVal, ElTy).IntVal != 0) {
Dest = cast<BasicBlock>(i.getCaseSuccessor());
break;
}
}
} else
for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
IntegersSubset::Range r = Case.getItem(n);
// FIXME: Currently work with ConstantInt based numbers.
const ConstantInt *LowCI = r.getLow().toConstantInt();
const ConstantInt *HighCI = r.getHigh().toConstantInt();
GenericValue Low = getOperandValue(const_cast<ConstantInt*>(LowCI), SF);
GenericValue High = getOperandValue(const_cast<ConstantInt*>(HighCI), SF);
if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 &&
executeICMP_ULE(CondVal, High, ElTy).IntVal != 0) {
Dest = cast<BasicBlock>(i.getCaseSuccessor());
break;
}
}
}
if (!Dest) Dest = I.getDefaultDest(); // No cases matched: use default
SwitchToNewBasicBlock(Dest, SF);

View File

@ -169,11 +169,11 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions) {
// Otherwise, we can fold this switch into a conditional branch
// instruction if it has only one non-default destination.
SwitchInst::CaseIt FirstCase = SI->case_begin();
IntegersSubset CaseRanges = FirstCase.getCaseValueEx();
if (CaseRanges.getNumItems() == 1 && CaseRanges.isSingleNumber(0)) {
IntegersSubset& Case = FirstCase.getCaseValueEx();
if (Case.isSingleNumber()) {
// FIXME: Currently work with ConstantInt based numbers.
Value *Cond = Builder.CreateICmpEQ(SI->getCondition(),
CaseRanges.getItem(0).getLow().toConstantInt(),
Case.getSingleNumber(0).toConstantInt(),
"cond");
// Insert the new branch.
@ -183,7 +183,6 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions) {
// Delete the old switch.
SI->eraseFromParent();
return true;
}
}
return false;